文件有两个关键属性:“文件名”(通常写成一个单词) 和“路径”。路径指明了文件在计算机上的位置。 文件名中,最后一个句点之后的部分称为文件的“扩展名”,它指出了文件的类型。
路径中的 C:\
部分是“根文件夹”,
它包含了所有其他文件夹。在 Windows 中,
根文件夹名为 C:\
,也称为C:盘。
在OS X 和 Linux 中,根文件夹是 /
。
这是两种风格不同的表达方式。
附加卷,诸如 DVD 驱动器或 USB 闪存驱动器,在不同的操作系统上显示也不同。在 Windows 上,它们表示为新的、
带字符的根驱动器。诸如 D:\
或 E:\
。
在OS X上,它们表示为新的文件夹,在 /Volumes
文件夹下。
在 Linux 上,它们表示为新的文件夹,在 /mnt("mount")
文件夹下。
同时也要注意,虽然文件夹名称和文件名在Windows和OS X上是不区分大小写的,但在Linux上是区分大小写的。
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
import os
os.getcwd()
'/home/jovyan/work/jupylab_houxue/pt04_essential/ch01_文件管理'
os.chdir('/tmp')
os.getcwd()
'/tmp'
这里,当前工作目录设置为 /tmp
, 如果使用文件名project.docx
,则会指向 /tmp/project.docx
。
如果要更改的当前工作目录不存在, Python就会显示一个错误。
# 以下路径不存在,会报错。
os.chdir('C:\\ThisFolderDoesNotExist')
注意:虽然文件夹是目录的更新的名称, 但请注意,当前工作目录(或当前目录)是标准术语, 没有当前工作文件夹这种说法。
绝对路径与相对路径
有两种方法指定一个文件路径。
- “绝对路径”,总是从根文件夹开始。
- “相对路径”,它相对于程序的当前工作目录。
还有点( .
)和点点( ..
)文件夹。它们不是真正的文件夹,
而是可以在路径中使用的特殊名称。单个的句点(“点”)
用作文件夹目名称时,是“这个目录”的缩写。
两个句点(“点点”)意思是父文件夹。
相对路径开始处的 .\
是可选的。
例如, .\spam.txt
和 spam.txt
指的是同一个文件。
os.makedirs()
创建新文件夹
程序可以用 os.makedirs()
函数创建新文件夹(目录)。
在交互式环境中输入以下代码:
import os
if os.path.exists('/tmp/delicious/walnut/waffles'):
pass
else:
os.makedirs('/tmp/delicious/walnut/waffles')
这不仅将创建 /tmp/delicious
文件夹,
也会在 /tmp/delicious
下创建 walnut
文件夹,
并在 /tmp/delicious/walnut
中创建 waffles
文件夹。
也就是说,os.makedirs()
将创建所有必要的中间文件夹,目的是确保完整路径名存在。
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
。
os.path
模块提供了一些函数,
返回一个相对路径的绝对路径,
以及检查给定的路径是否为绝对路径。
- 调用
os.path.abspath(path)
将返回参数的绝对路径的字符串。这是将相对路径转换为绝对路径的简便方法。 - 调用
os.path.isabs(path)
,如果参数是一个绝对路径,就返回True
,如果参数是一个相对路径,就返回False
。 - 调用
os.path.relpath(path,start)
将返回从start
路径到path
的相对路径的字符串。如果没有提供start
,就使用当前工作目录作为开始路径。
在交互式环境中尝试以下函数:
os.path.abspath('.')
'/tmp'
os.path.abspath('./Scripts')
'/tmp/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()
'/tmp'
调用 os.path.dimame(path)
将返回一个字符串,
它包含 path
参数中最后一个斜杠之前的所有内容。
调用 os.path.basename(path)
将返回一个字符串,
它包含 path
参数中最后一个斜杠之后的所有内容。
基本名称跟在路径中最后一个斜杠后,它和文件名一样, 目录名称是最后一个斜杠之前的所有内容。 例如,在交互式环境中输入以下代码:
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.dimame()
和 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
,就能在所有操作系统上工作。
查看文件大小和文件夹内容
一旦有办法处理文件路径,就可以开始搜集特定文件和文件夹的信息。
os.path
模块提供了一些函数,
用于查看文件的字节数以及给定文件夹中的文件和子文件夹。
- 调用
os.path.getsize(path)
将返回path
参数中文件的字节数。 - 调用
os.listdir(path)
将返回文件名字符串的列表,包含path
参数中的每个文件(请注意,这个函数在os
模块中,而不是os.path
)。
下面是在交互式环境中尝试这些函数的结果:
os.path.getsize('sec01_filepath.ipynb')
os.listdir( '.')
['delicious']
可以看到,计算机上的 calc.exe
程序是776192字节。在 C:\\Windows\\System32
下有许多文件。
如果想知道这个目录下所有文件的总字节数,就可以同时使用s.path.getsize()
和os.listdir()
。
totalSize = 0
for filename in os.listdir('.'):
totalSize = totalSize + os.path.getsize(os.path.join('.', filename))
print (totalSize)
20
当循环遍历 C:\\Windows\System32
文件夹中的每个文件时,
totalSize
变量依次增加每个文件的字节数。
请注意,在调用 os.path.getsize()
时,
使用了 os.path.join()
来连接文件夹名称和当前的文件名。
os.path.getsize()
返回的整数添加到 totalSize
中。在循环遍历所有文件后,
打印出 totalSize
,看看 C:\\Windows\System32
文件夹的总字节数。
检查路径有效性
如果提供的路径不存在,许多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('/home/shaopp/jubook/')
False
os.path.exists('/home/shaopp/jubooks/')
False
os.path.isdir('/home/shaopp/jubook/ch08_io_文件读写/')
False
os.path.isfile('/home/shaopp/jubook/ch08_io_文件读写/')
False
os.path.isdir('/home/shaopp/jubook/ch08_io_文件读写/sec01_文件与文件路径.ipynb')
False
os.path.isfile( '/home/shaopp/jubook/ch08_io_文件读写/sec01_文件与文件路径.ipynb')
False
利用 os.path.exists()
函数,
可以确定 DVD 或闪存盘当前是否连在计算机上。
例如,如果在 Windows 计算机上,
想用卷名 D:\
检查一个闪存盘,可以这样做:
os.path.exists('D:\\')
False
看起来忘记插入闪存盘了。