- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
8.1 文件与文件路径
文件有两个关键属性:“文件名”(通常写成一个单词)和“路径”。路径指明了文件在计算机上的位置。例如,我的 Windows 7 笔记本上有一个文件名为projects.docx,它的路径在C:\Users\asweigart\Documents。文件名中,最后一个句点之后的部分称为文件的“扩展名”,它指出了文件的类型。project.docx是一个Word文档,Users、asweigart和Documents都是指“文件夹”(也成为目录)。文件夹可以包含文件和其他文件夹。例如,project.docx在Documents文件夹中,该文件夹又在asweigart文件夹中,asweigart文件夹又在Users文件夹中。图8-1展示了这个文件夹的组织结构。
路径中的C:\部分是“根文件夹”,它包含了所有其他文件夹。在Windows中,根文件夹名为C:\,也称为C:盘。在OS X和Linux中,根文件夹是/。在本书中,我使用Windows风格的根文件夹,C:\。如果你在OS X或Linux上输入交互式环境的例子,请用/代替。
图8-1 在文件夹层次结构中的一个文件
附加卷,诸如DVD驱动器或USB闪存驱动器,在不同的操作系统上显示也不同。在Windows上,它们表示为新的、带字符的根驱动器。诸如D:\或E:\。在OS X上,它们表示为新的文件夹,在/Volumes文件夹下。在Linux上,它们表示为新的文件夹,在/mnt("mount")文件夹下。同时也要注意,虽然文件夹名称和文件名在Windows和OS X上是不区分大小写的,但在Linux上是区分大小写的。
8.1.1 Windows上的倒斜杠以及OS X和Linux上的正斜杠
在Windows上,路径书写使用倒斜杠作为文件夹之间的分隔符。但在OS X和Linux上,使用正斜杠作为它们的路径分隔符。如果想要程序运行在所有操作系统上,在编写Python脚本时,就必须处理这两种情况。
好在,用os.path.join()函数来做这件事很简单。如果将单个文件和路径上的文件夹名称的字符串传递给它,os.path.join()就会返回一个文件路径的字符串,包含正确的路径分隔符。在交互式环境中输入以下代码:
>>> import os >>> os.path.join('usr', 'bin', 'spam') 'usr\\bin\\spam'
我在Windows上运行这些交互式环境的例子,所以,os.path .join('usr', 'bin', 'spam')返回'usr\bin\spam'(请注意,倒斜杠有两个,因为每个倒斜杠需要由另一个倒斜杠字符来转义)。如果我在OS X或Linux上调用这个函数,该字符串就会是'usr/bin/spam'。
如果需要创建文件名称的字符串,os.path.join()函数就很有用。这些字符串将传递给几个文件相关的函数,本章将进行介绍。例如,下面的例子将一个文件名列表中的名称,添加到文件夹名称的末尾。
>>> myFiles = ['accounts.txt', 'details.csv', 'invite.docx'] >>> for filename in myFiles: print(os.path.join('C:\\Users\\asweigart', filename)) C:\Users\asweigart\accounts.txt C:\Users\asweigart\details.csv C:\Users\asweigart\invite.docx
8.1.2 当前工作目录
每个运行在计算机上的程序,都有一个“当前工作目录”,或cwd。所有没有从根文件夹开始的文件名或路径,都假定在当前工作目录下。利用os.getcwd()函数,可以取得当前工作路径的字符串,并可以利用os.chdir()改变它。在交互式环境中输入以下代码:
>>> import os >>> os.getcwd() 'C:\\Python34' >>> os.chdir('C:\\Windows\\System32') >>> os.getcwd() 'C:\\Windows\\System32'
这里,当前工作目录设置为C:\Python34,所以文件名project.docx指向C:\Python34\project.docx。如果我们将当前工作目录改为C:\Windows,文件就被解释为C:\Windows\project.docx。
如果要更改的当前工作目录不存在,Python就会显示一个错误。
>>> os.chdir('C:\\ThisFolderDoesNotExist') Traceback (most recent call last): File "< pyshell#18>", line 1, in < module> os.chdir('C:\\ThisFolderDoesNotExist') FileNotFoundError: [WinError 2] The system cannot find the file specified: 'C:\\ThisFolderDoesNotExist'
注意
虽然文件夹是目录的更新的名称,但请注意,当前工作目录(或当前目录)是标准术语,没有当前工作文件夹这种说法。
8.1.3 绝对路径与相对路径
有两种方法指定一个文件路径。
· “绝对路径”,总是从根文件夹开始。
· “相对路径”,它相对于程序的当前工作目录。
还有点(.)和点点(..)文件夹。它们不是真正的文件夹,而是可以在路径中使用的特殊名称。单个的句点(“点”)用作文件夹目名称时,是“这个目录”的缩写。两个句点(“点点”)意思是父文件夹。
图8-2是一些文件夹和文件的例子。如果当前工作目录设置为C:\bacon,这些文件夹和文件的相对目录,就设置为图8-2所示的样子。
图8-2 在工作目录C:\bacon中的文件夹和文件的相对路径
相对路径开始处的.\是可选的。例如,.\spam.txt和spam.txt指的是同一个文件。
8.1.4 用os.makedirs()创建新文件夹
程序可以用os.makedirs()函数创建新文件夹(目录)。在交互式环境中输入以下代码:
>>> import os >>> os.makedirs('C:\\delicious\\walnut\\waffles')
这不仅将创建C:\delicious文件夹,也会在C:\delicious下创建walnut文件夹,并在C:\delicious\walnut中创建waffles文件夹。也就是说,os.makedirs()将创建所有必要的中间文件夹,目的是确保完整路径名存在。图 8-3 展示了这个文件夹的层次结构。
图8-3 os.makedirs('C:\delicious\walnut\waffles')的结果
8.1.5 os.path模块
os.path模块包含了许多与文件名和文件路径相关的有用函数。例如,你已经使用了os.path.join()来构建所有操作系统上都有效的路径。因为os.path是os模块中的模块,所以只要执行import os就可以导入它。如果你的程序需要处理文件、文件夹或文件路径,就可以参考本节中这些简短的例子。os.path模块的完整文档在Python网站上:http://docs.python.org/3/library/os.path.html。
注意
本章后面的大多数例子都需要os模块,所以要记得在每个脚本开始处导入它,或在重新启动IDLE时导入它。否则,就会遇到错误消息NameError: name 'os' is not defined。
8.1.6 处理绝对路径和相对路径
os.path模块提供了一些函数,返回一个相对路径的绝对路径,以及检查给定的路径是否为绝对路径。
· 调用os.path.abspath(path)将返回参数的绝对路径的字符串。这是将相对路径转换为绝对路径的简便方法。
· 调用os.path.isabs(path),如果参数是一个绝对路径,就返回True,如果参数是一个相对路径,就返回False。
· 调用os.path.relpath(path, start)将返回从start路径到path的相对路径的字符串。如果没有提供start,就使用当前工作目录作为开始路径。
在交互式环境中尝试以下函数:
>>> os.path.abspath('.') 'C:\\Python34' >>> os.path.abspath('.\\Scripts') 'C:\\Python34\\Scripts' >>> os.path.isabs('.') False >>> os.path.isabs(os.path.abspath('.')) True
因为在os.path.abspath()调用时,当前目录是C:\Python34,所以“点”文件夹指的是绝对路径'C:\Python34'。
注意
因为在你的系统上,文件和文件夹可能与我的不同,所以你不能完全遵照本章中的每一个例子。但还是请尝试用你的计算机上存在的文件夹来完成例子。
在交互式环境中,输入以下对os.path.relpath()的调用:
>>> os.path.relpath('C:\\Windows', 'C:\\') 'Windows' >>> os.path.relpath('C:\\Windows', 'C:\\spam\\eggs') '..\\..\\Windows' >>> os.getcwd() 'C:\\Python34'
调用os.path.dirname(path)将返回一个字符串,它包含path参数中最后一个斜杠之前的所有内容。调用os.path.basename(path)将返回一个字符串,它包含path 参数中最后一个斜杠之后的所有内容。一个路径的目录名称和基本名称如图8-4所示。
图8-4 基本名称跟在路径中最后一个斜杠后,它和文件名一样,
目录名称是最后一个斜杠之前的所有内容
例如,在交互式环境中输入以下代码:
>>> path = 'C:\\Windows\\System32\\calc.exe' >>> os.path.basename(path) 'calc.exe' >>> os.path.dirname(path) 'C:\\Windows\\System32'
如果同时需要一个路径的目录名称和基本名称,就可以调用os.path.split(),获得这两个字符串的元组,像这样:
>>> calcFilePath = 'C:\\Windows\\System32\\calc.exe' >>> os.path.split(calcFilePath) ('C:\\Windows\\System32', 'calc.exe')
请注意,可以调用os.path.dirname()和os.path.basename(),将它们的返回值放在一个元组中,从而得到同样的元组。
>>> (os.path.dirname(calcFilePath), os.path.basename(calcFilePath)) ('C:\\Windows\\System32', 'calc.exe')
但如果需要两个值,os.path.split()是很好的快捷方式。
同时也请注意,os.path.split()不会接受一个文件路径并返回每个文件夹的字符串的列表。如果需要这样,请使用split()字符串方法,并根据os.path.sep中的字符串进行分割。回忆一下,根据程序运行的计算机,os.path.sep变量设置为正确的文件夹分割斜杠。
例如,在交互式环境中输入以下代码:
>>> calcFilePath.split(os.path.sep) ['C:', 'Windows', 'System32', 'calc.exe']
在OS X和Linux系统上,返回的列表头上有一个空字符串:
>>> '/usr/bin'.split(os.path.sep) ['', 'usr', 'bin']
split()字符串方法将返回一个列表,包含该路径的所有部分。如果向它传递os.path.sep,就能在所有操作系统上工作。
8.1.7 查看文件大小和文件夹内容
一旦有办法处理文件路径,就可以开始搜集特定文件和文件夹的信息。os.path模块提供了一些函数,用于查看文件的字节数以及给定文件夹中的文件和子文件夹。
· 调用os.path.getsize(path)将返回path参数中文件的字节数。
· 调用os.listdir(path)将返回文件名字符串的列表,包含path参数中的每个文件(请注意,这个函数在os模块中,而不是os.path)。
下面是我在交互式环境中尝试这些函数的结果:
>>> os.path.getsize('C:\\Windows\\System32\\calc.exe') 776192 >>> os.listdir('C:\\Windows\\System32') ['0409', '12520437.cpx', '12520850.cpx', '5U877.ax', 'aaclient.dll', --_snip_-- 'xwtpdui.dll', 'xwtpw32.dll', 'zh-CN', 'zh-HK', 'zh-TW', 'zipfldr.dll']
可以看到,我的计算机上的calc.exe程序是776192字节。在我的C:\Windows\ system32下有许多文件。如果想知道这个目录下所有文件的总字节数,就可以同时使用os.path.getsize()和os.listdir()。
>>> totalSize = 0 >>> for filename in os.listdir('C:\\Windows\\System32'): totalSize = totalSize + os.path.getsize(os.path.join('C:\\Windows\\System32', filename)) >>> print(totalSize) 1117846456
当循环遍历C:\Windows\System32文件夹中的每个文件时,totalSize变量依次增加每个文件的字节数。请注意,我在调用os.path.getsize()时,使用了os.path.join()来连接文件夹名称和当前的文件名。os.path.getsize()返回的整数添加到totalSize中。在循环遍历所有文件后,我打印出totalSize,看看C:\Windows\System32文件夹的总字节数。
8.1.8 检查路径有效性
如果你提供的路径不存在,许多Python函数就会崩溃并报错。os.path模块提供了一些函数,用于检测给定的路径是否存在,以及它是文件还是文件夹。
· 如果path参数所指的文件或文件夹存在,调用os.path.exists(path)将返回True,否则返回False。
· 如果path参数存在,并且是一个文件,调用os.path.isfile(path)将返回True,否则返回False。
· 如果path参数存在,并且是一个文件夹,调用os.path.isdir(path)将返回True,否则返回False。
下面是我在交互式环境中尝试这些函数的结果:
>>> os.path.exists('C:\\Windows') True >>> os.path.exists('C:\\some_made_up_folder') False >>> os.path.isdir('C:\\Windows\\System32') True >>> os.path.isfile('C:\\Windows\\System32') False >>> os.path.isdir('C:\\Windows\\System32\\calc.exe') False >>> os.path.isfile('C:\\Windows\\System32\\calc.exe') True
利用os.path.exists()函数,可以确定DVD或闪存盘当前是否连在计算机上。例如,如果在Windows计算机上,我想用卷名D:\检查一个闪存盘,可以这样做:
>>> os.path.exists('D:\\') False
不好!看起来我忘记插入闪存盘了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论