文件与文件路径

路径合成 os.path.join()

在Windows上,路径中以倒斜杠作为文件夹之间的分隔符,Linux或OS X中则是正斜杠。如果想要程序正确运行于所有操作系统上,就必须要处理这种情况。os.path.join()方法可以正确的根据不同的操作系统来合成路径,它的用法如下:

  1. >>> import os
  2. >>> os.path.join("Program", "QQ", "Pet")
  3. 'Program\\QQ\\Pet' # 在windows下返回的结果
  4. 'Program/QQ/Pet' # 在Linux或OS X下返回的结果
  5. >>> myFiles = ["accounts.txt", "details.csv", "invite.docx"]
  6. >>> for filename in myFiles:
  7. ... print(os.path.join("C:\\Users\\Dereen", filename))
  8. C:\Users\Dereen\accounts.txt
  9. C:\Users\Dereen\details.csv
  10. C:\Users\Dereen\invite.docx

查看并改变当前工作目录

使用os.getcwd()来获取当前工作目录,使用os.chdir()来改变当前工作目录。这么做的意义是所有没有从根文件夹开始的文件名或路径,都假定在当前工作目录下。如果当前工作目录错误容易引发各种该问题,或者不想用当前工作目录作为根目录,而是想用别的目录作为根目录。

  1. >>> os.getcwd()
  2. 'F:\\Learn\\Automate-the-Boring-Stuff-with-Python-Solutions'
  3. >>> os.chdir("C:\\Windows\\system32")
  4. >>> os.getcwd()
  5. 'C:\\Windows\\system32'

绝对路径与相对路径

  • “绝对路径”:总是从根文件夹开始;
  • “相对路径”:它相对于程序的当前工作目录。

例如:C:\Program Files\QQ\music

假如当前工作目录为C:\Program Files,则对music文件夹来说,其相对路径为:.\QQ\music,绝对路径为:C:\Program Files\QQ\music

创建新文件夹 os.makedirs()

  1. >>> os.makedirs(".\\color\\green")

上面这个命令会直接在当前文件夹下创建新文件夹color并在其下创建新文件夹green

绝对路径与相对路径互转

  • 相对路径转绝对路径:os.path.abspath(path)将返回参数的绝对路径的字符串。
  • 绝对路径转相对路径:os.path.relpath(path, start)将返回从start路径到path路径的相对路径的字符串。(如果没有提供start,就是用当前工作目录作为开始路径)
  • 判断一个路径是否为绝对路径:os.isabs(path)如果是就返回True,不是就返回False。

例子:

  1. >>> os.path.abspath(".")
  2. 'F:\\Learn\\Automate-the-Boring-Stuff-with-Python-Solutions'
  3. >>> os.path.relpath("C:\\Windows", "C:\\Hello\Kitty\S")
  4. '..\\..\\..\\Windows'
  5. >>> os.path.isabs(".")
  6. False

目录名称和基本名称(路径分割)

os.path.dirname(path)返回path参数中最后一个斜杠之前的所有内容;os.path.basename(path)返回path参数中最后一个斜杠之后的所有内容。os.path.split(path)返回一个元组,同时包含2者。

例子:

  1. >>> path = "C:\\Windows\\system32\\tasks\\calc.exe"
  2. >>> os.path.dirname(path)
  3. 'C:\\Windows\\system32\\tasks'
  4. >>> os.path.basename(path)
  5. 'calc.exe'
  6. >>> os.path.split(path)
  7. ('C:\\Windows\\system32\\tasks', 'calc.exe')

如果想要路径进行进一步的分割,就要调用字符串中的split()方法。并向其传入os.path.sep参数。(os.path.sep在不同的操作系统下,值也不同,在windows下值为"\"),例子:

  1. >>> path.split(os.path.sep)
  2. ['C:', 'Windows', 'system32', 'tasks', 'calc.exe']

查看文件大小和文件夹内容

使用os.path.getsize(filepath)来查看单个文件的大小,注意不能查看文件夹的大小。使用os.listdir(path)来查看该目录下的所有文件及文件夹。二者组合使用可以计算文件夹的大小。例如:

  1. >>> os.path.getsize("C:\\Windows\\System32\\calc.exe")
  2. 27648
  3. >>> os.listdir("C:\\Windows\\System32")
  4. ['0409', '@AppHelpToast.png', '@AudioToastIcon.png', '@BackgroundAccessToastIcon.png', '@bitlockertoastimage.png', '@edptoastimage.png', '@EnrollmentToastIcon.png',
  5. --snip--
  6. 'xwreg.dll', 'xwtpdui.dll', 'xwtpw32.dll', 'zh-CN', 'zh-HANS', 'zh-TW', 'zipcontainer.dll', 'zipfldr.dll', 'ztrace_maps.dll']
  7. >>> totalSize = 0
  8. >>> for file in os.listdir("C:\\Windows\\System32"):
  9. ... totalSize += os.path.getsize(os.path.join("C:\\Windows\\System32", file))
  10. ...
  11. >>> print(totalSize)
  12. 2249563697

检查路径有效性

使用os.path.exists(path)检查path所指的文件或文件夹是否存在;os.path.isdir()检查参数path传入的值是否为一个文件夹;os.path.isfile()检查参数path传入的值是否为一个文件。例如;

  1. >>> os.path.exists(r"C:\Windows")
  2. True
  3. >>> os.path.isdir(r"C:\Windows")
  4. True
  5. >>> os.path.isfile(r"C:\Windows")
  6. False

文件读写过程

在开始前先介绍一下文件的分类:

  • 纯文本文件:只包含基本文本字符,不包含字体、大小、颜色和其他信息。例如:.txt文件、.md文件和.py文件;
  • 二进制文件:所有其他文件类型,例如.pdf文件、.docx文件等;使用纯文本文件编辑器打开一个二进制文件就会显示乱码,如图:

在Python中,读写文件有3个步骤:

  1. 调用open()函数,返回一个File对象;
  2. 调用File对象的read()write()方法;
  3. 调用File对象的close()方法,关闭该文件。

打开文件

使用open()函数打开文件,在打开文件时可同时传入参数(默认为‘r’,只读模式)。该函数会返回一个对象,该对象包含文档内容以及名称、打开模式以及文档编码模式。例如:

  1. >>> content = open("README.md", "w")
  2. >>> content
  3. <_io.TextIOWrapper name='README.md' mode='w' encoding='UTF-8'>
传递参数 含义
r 只读模式打开,即只能读取文件内容不能写入
w 可以写入内容,但是会清除原文档所有内容
x 用于创建并写新文档
a 用于在文档尾部进行扩展(不会清除原文档内容)

读取文件内容

在上一步中,我们使用open()函数打开文件并返回了一个文件对象,这里,我们可以使用read()readlines()方法读取这个文件对象中的内容。其中,前者将文件中的所有内容读取为一个大字符串,后者按行读取文件,每行为一个字符串并最终形成一个列表。

  1. >>> contentFile = open("hello.txt")
  2. >>> contentFile.readlines()
  3. ['How are you?\n', "I'm fine, thanks, and you?\n", "I'm fine, too."]
  4. >>> contentFile.read()
  5. ''
  6. >>> contentFile.seek(0)
  7. 0
  8. >>> contentFile.read()
  9. "How are you?\nI'm fine, thanks, and you?\nI'm fine, too."

上面的代码中,由于先使用了readlines()方法,所以在使用read()方法时,文件指针已经到了第四行,而第四行是没有内容的,所以read()方法返回的值为空。为了解决这个问题我们使用seed()方法,将文件指针重新指向第1行。然后在执行接下来的read()操作就可以了。

写入文件

使用write()方法向文件中写入新内容。当以只读模式打开时,不能写入新内容。以w模式打开文件写入时会覆盖掉文件中所有原内容,以a模式打开文件写入时会在文件尾部插入新内容。

当打开的文件不存在时,wa模式都会新建一个文件并写入内容。在读取或写入后,要调用close()方法,然后才能再次打开该文件。

  1. >>> contentFile.close()
  2. >>> contentFile = open("hello.txt", "a")
  3. >>> contentFile.write("Thank you!")
  4. 10
  5. >>> contentFile.close()
  6. >>> contentFile = open("hello.txt")
  7. >>> contentFile.read()
  8. "How are you?\nI'm fine, thanks, and you?\nI'm fine, too.Thank you!"

用shelve模块保存变量

利用shelve模块,可以将Python程序中的变量保存到二进制的shelf文件中。这样,程序就可以从硬盘中恢复变量的数据。shelve模块相当于让我们在程序中增加“保存”和“打开”功能。例如,运行一个程序,并输入了一些配置设置,就可以将这些设置保存到一个shelf文件,然后让程序下一次运行时加载它们。

  1. >>> import shelve
  2. >>> shelfFile = shelve.open("mydata")
  3. >>> cats = ["Libai", "Dufu", 'Zhupi', 'Zhongfen']
  4. >>> shelfFile['cats'] = cats
  5. >>> shelfFile.close()

这个程序会在当前目录下生成三个文件:mydata.bakmydata.datmydata.dir

  1. >>> shelfFile = shelve.open('mydata')
  2. >>> type(shelfFile)
  3. <class 'shelve.DbfilenameShelf'>
  4. >>> shelfFile['cats']
  5. ['Libai', 'Dufu', 'Zhupi', 'Zhongfen']
  6. >>> shelfFile.close()

上面的代码检查了shelfFile中的内容,像字典一样,shelf值有keys()values()方法,返回shelf中键和值的类似列表的值。要想使用它们,我们还要把它们转化为列表类型:

  1. >>> shelfFile = shelve.open('mydata')
  2. >>> list(shelfFile.keys())
  3. ['cats']
  4. >>> list(shelfFile.values())
  5. [['Libai', 'Dufu', 'Zhupi', 'Zhongfen']]
  6. >>> list(shelfFile.values())[0]
  7. ['Libai', 'Dufu', 'Zhupi', 'Zhongfen']
  8. >>> shelfFile.close()

使用pprint.pformat()函数保存变量

pprint()是一种将列表、字典或元组以更漂亮、规范的格式输出的一个方法。我们可以利用pprint.pformat()函数将变量写入.py文件。该文件将成为一个模块,方便我们下次进行使用。而且与shelve模块中的方法不同的事,.py文件能够方便的使用一些常见的记事本文件打开查看。例子:

  1. >>> import pprint
  2. >>> cats = [{'name': 'Libai', 'color': 'White'}, {'name': 'Zhupi', 'color': 'Orange'}]
  3. >>> pprint.pformat(cats)
  4. "[{'color': 'White', 'name': 'Libai'}, {'color': 'Orange', 'name': 'Zhupi'}]"
  5. >>> file = open('myCats.py', 'w')
  6. >>> file.write('cats = ' + pprint.pformat(cats) + '\n')
  7. 83
  8. >>> file.close()
  9. >>> import myCats
  10. >>> myCats.cats
  11. [{'color': 'White', 'name': 'Libai'}, {'color': 'Orange', 'name': 'Zhupi'}]
  12. >>> myCats.cats[0]
  13. {'color': 'White', 'name': 'Libai'}
  14. >>> myCats.cats[0]['name']
  15. 'Libai'

值得注意的是,对于大多数的应用,我们还是利用shelve模块来保存数据。只有基本数据类型,例如整型、浮点型、字符串、列表和字典等,可以用这个方法当做简单文本写入文件。

小项目一(随机测验试卷生成)

假如一位老师要考察班上35名同学对于美国50个州首府的了解情况,他打算用选择题的形式来考察。但是为了防止有人作弊,他打算将题目的顺序打乱且每道题目的选项中除了正确的那个,其他的都是从其他49个州的首府中随机抽取的,那么下面的代码会很有用:

  1. # randomQuizGenerator.py - Create quizzes with questions and answers in random order, along with the answer key.
  2. import random
  3. # The quiz data. Key are states and values are their capitals.
  4. capitals = {
  5. 'Alabama': 'Montgomery',
  6. 'Alaska': 'Juneau',
  7. 'Arizona': 'Phoenix',
  8. 'Arkansas': 'Little Rock',
  9. 'California': 'Sacramento',
  10. 'Colorado': 'Denver',
  11. 'Connecticut': 'Hartford',
  12. 'Delaware': 'Dover',
  13. 'Florida': 'Tallahassee',
  14. 'Georgia': 'Atlanta',
  15. 'Hawaii': 'Honolulu',
  16. 'Idaho': 'Boise',
  17. 'Illinois': 'Springfield',
  18. 'Indiana': 'Indianapolis',
  19. 'Iowa': 'Des Monies',
  20. 'Kansas': 'Topeka',
  21. 'Kentucky': 'Frankfort',
  22. 'Louisiana': 'Baton Rouge',
  23. 'Maine': 'Augusta',
  24. 'Maryland': 'Annapolis',
  25. 'Massachusetts': 'Boston',
  26. 'Michigan': 'Lansing',
  27. 'Minnesota': 'Saint Paul',
  28. 'Mississippi': 'Jackson',
  29. 'Missouri': 'Jefferson City',
  30. 'Montana': 'Helena',
  31. 'Nebraska': 'Lincoln',
  32. 'Nevada': 'Carson City',
  33. 'New Hampshire': 'Concord',
  34. 'New Jersey': 'Trenton',
  35. 'New Mexico': 'Santa Fe',
  36. 'New York': 'Albany',
  37. 'North Carolina': 'Raleigh',
  38. 'North Dakota': 'Bismarck',
  39. 'Ohio': 'Columbus',
  40. 'Oklahoma': 'Oklahoma City',
  41. 'Oregon': 'Salem',
  42. 'Pennsylvania': 'Harrisburg',
  43. 'Rhode Island': 'Providence',
  44. 'South Carolina': 'Columbia',
  45. 'South Dakota': 'Pierre',
  46. 'Tennessee': 'Nashville',
  47. 'Texas': 'Austin',
  48. 'Utah': 'Salt Lake City',
  49. 'Vermont': 'Montpelier',
  50. 'Virginia': 'Richmond',
  51. 'Washington': 'Olympia',
  52. 'West Virginia': 'Charleston',
  53. 'Wisconsin': 'Madison',
  54. 'Wyoming': 'Cheyenne'
  55. }
  56. # Generate 35 quiz files.
  57. for quizNum in range(35):
  58. # Create the quiz and answer key files.
  59. quizFile = open('capitalsquiz%s.txt' % (quizNum + 1), 'w')
  60. answerKeyFile = open('capitalsquiz_answers%s.txt' % (quizNum + 1), 'w')
  61. # Write out the header for the quiz.
  62. quizFile.write('Name:\n\nDate:\n\nPeriod:\n\n')
  63. quizFile.write((' ' * 20) + 'State Capitals Quiz (Form %s)' % (quizNum + 1))
  64. quizFile.write('\n\n')
  65. # Shuffle the order of the states.
  66. states = list(capitals.keys())
  67. random.shuffle(states)
  68. # Loop through all 50 states, making a question for each.
  69. for questionNum in range(50):
  70. # Get right and wrong answers.
  71. correctAnswer = capitals[states[questionNum]]
  72. wrongAnswers = list(capitals.values())
  73. del wrongAnswers[wrongAnswers.index(correctAnswer)]
  74. wrongAnswers = random.sample(wrongAnswers, 3)
  75. answerOptions = wrongAnswers + [correctAnswer]
  76. random.shuffle(answerOptions)
  77. # Write the question and the answer options to the quiz file.
  78. quizFile.write('%s. What is the capital of %s?\n' % (questionNum + 1, states[questionNum]))
  79. for i in range(4):
  80. quizFile.write('%s. %s\n' % ('ABCD' [i], answerOptions[i]))
  81. quizFile.write('\n')
  82. # Write the answer key to a file.
  83. answerKeyFile.write('%s. %s\n' % (questionNum + 1, 'ABCD' [answerOptions.index(correctAnswer)]))
  84. quizFile.close()
  85. answerKeyFile.close()

小项目二(多重剪贴板)

这个代码实现了一个简单的功能,即将剪贴板中的内容以关键字的方式保存,而且可以以关键字的方式提取,相当于一个暂存(多重)剪贴板。

  1. # mab.pyw - Saves and loads pieces of text to the clipboard.
  2. # Usage: py.exe mcb.pyw save <keyword> - Saves clipboard to keyword.
  3. # py.exe mcb.pyw <keyword> - Loads keyword to clipboard.
  4. # py.exe mcb.pyw list - Loads all keywords to clipboard.
  5. import shelve
  6. import pyperclip
  7. import sys
  8. mcbShelf = shelve.open('mcb')
  9. # Save clipboard content.
  10. if len(sys.argv) == 3 and sys.argv[1].lower() == 'save':
  11. mcbShelf[sys.argv[2]] = pyperclip.paste()
  12. elif len(sys.argv) == 2:
  13. # List keywords and load content.
  14. if sys.argv[1].lower() == 'list':
  15. pyperclip.copy(str(list(mcbShelf.keys())))
  16. elif sys.argv[1] in mcbShelf:
  17. pyperclip.copy(mcbShelf[sys.argv[1]])
  18. mcbShelf.close()

[Python学习笔记]系列是我在学习《Python编程快速上手——让繁琐工作自动化(Automate The Boring Stuff With Python)》这本书时的学习笔记。通过自己再手敲一遍概念和代码,方便自己记忆和日后查阅。如果对你有帮助,那就更好了!

[Python学习笔记]文件的读取写入的更多相关文章

  1. Python学习笔记之将数据写入到文件中

    10-3 访客:编写一个程序,提示用户输入其名字:用户作出响应后,将其名字写入到文件guest.txt 中. 编写Python代码: username = input("Please ent ...

  2. Python学习笔记——文件

    1.文件只是连续的字节序列 open()内建函数是打开文件之门的钥匙 file_obj=open(file_name,access_mode='r/w/a,' buffering=-1) file_n ...

  3. Python学习笔记——文件操作

    python中,一切皆对象.   一.文件操作流程 (1)打开文件,得到一个文件句柄(对象),赋给一个对象: (2)通过文件句柄对文件进行操作: (3)关闭文件. 文件对象f通过open()函数来创建 ...

  4. python学习笔记---文件的操作

    数据的保存: 1.内存:常用的变量2.文件:文本内容,二进制的文件内容3.数据库: 读文件:1.要读取的文件路径一定要存在.2.打开存在的文件:open函数    参数1:文件的路径,相对的或者是绝对 ...

  5. 03 python学习笔记-文件操作(三)

    本文内容主要包括以下方面: 1. 文件操作基本认识2. 只读(r, rb)3. 只写(w, wb)4. 追加(a, ab)5. r+读写6. w+写读7. a+写读(追加写读)8. 文件的修改 一.文 ...

  6. python 学习笔记---文件处理

    1.打开文件读取数据 f =open(“wenjian.txt”,"r") print(f) f.close() 直接变成列表--->list(f) for each_lin ...

  7. Python学习笔记——文件写入和读取

    1.文件写入 #coding:utf-8 #!/usr/bin/env python 'makeTextPyhton.py -- create text file' import os ls = os ...

  8. python学习笔记:文件操作和集合(转)

    转自:http://www.nnzhp.cn/article/16/ 这篇博客来说一下python对文件的操作. 对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句 ...

  9. Python学习笔记_Python向Excel写入数据

    实验环境 1.OS:Win 10 64位 2.Python 3.7 3.如果没有安装xlwt库,则安装:pip install xlwt 下面是从网上找到的一段代码,网上这段代码,看首行注释行,是在L ...

随机推荐

  1. c++面试笔试集锦

    1. char *const p 是指针常量,通俗的解释:指针本身是一个常量 也就是不能改变该指针的指向性,可以改变指向的量的值 const char *p 是常量指针,解释:指向常量的指针,指针指向 ...

  2. PyQt中ui编译成窗体.py,中文乱码

    我在Eric工具下编译的 解决办法: 1.打开 C:\Python27\Lib\site-packages\eric4\i18n,将中文资源包的名称"GB2312."去掉,变成er ...

  3. MySQL复合索引探究

    复合索引(又称为联合索引),是在多个列上创建的索引.创建复合索引最重要的是列顺序的选择,这关系到索引能否使用上,或者影响多少个谓词条件能使用上索引.复合索引的使用遵循最左匹配原则,只有索引左边的列匹配 ...

  4. .NET使用DinkToPdf将HTML转成PDF

    0.介绍 C# .NET Core wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to P ...

  5. 《C++ Primer》Chapter 7 [类]

    前言 在C++中,我们使用类定义自己得数据类型/通过定义新的类型来反应待解决的题的各种概念,是我们更容易编写.调试和修改程序. 我们需要主要关注数据抽象的重要性.数据抽象能帮助我们将对象的具体实现与对 ...

  6. [The Preliminary Contest for ICPC Asia Shanghai 2019] B-Light bulbs(差分+思维)

    前言 最近有很多算不上事的事,搞得有点心烦,补题难免就很水,没怎么搞,自我检讨一番~~ 说实话网络赛题目的质量还是挺高的,题目都设计的挺好的,很值得学习.这场比赛那会只有我们大二的在做,其他人去参加$ ...

  7. 2020牛客暑期多校训练营(第一场)Easy Integration

    传送门:J. Easy Integration 题意:给你n,求这个积分,最后的结果分子是记为p,分母记为q. 求(p*q-1)mod 998244353. 题解:比赛完看到巨巨说这是贝塔函数,我一搜 ...

  8. ACM#学习心得0

    加入实验室也有些日子了,这是第一个近来的小小学习心得 1.在之前的训练题和考核题以及平时刷过的题中,我发现自己对字符串这一块的基础知识掌握还是比较差的,总是不能正确的接收的字符或字符串. 这两个星期, ...

  9. Strategic game POJ - 1463 树型dp

    //题意:就是你需要派最少的士兵来巡查每一条边.相当于求最少点覆盖,用最少的点将所有边都覆盖掉//题解://因为这是一棵树,所以对于每一条边的两个端点,肯定要至少有一个点需要放入士兵,那么对于x-&g ...

  10. Codeforces Round #672 (Div. 2) A. Cubes Sorting (思维)

    题意:有一长度为\(n\)的一组数,每次可以交换两个数的位置,问能否在\(\frac{n*(n-1)}{2}-1\)次操作内使得数组非递减. 题解:不难发现,只有当整个数组严格递减的时候,操作次数是\ ...