文章目录
1. shutil 模块
shutil
(或称为 shell 工具)模块中包含一些函数,让你在 Python 程序中复制、移动、改名和删除文件。要使用 shutil 的函数,首先需要 import shutil
。
1.1 shutil.copy()复制文件和文件夹
调用 shutil.copy(source, destination)
将复制一个文件,将路径 source
处的文件复制到路径 destination
处的文件夹。如果 destination
是一个文件名,它将作为被复制文件的新名字。该函数返回一个字符串,表示被复制文件的路径。
>>> import shutil, os
>>> os.chdir('C:\\')
>>> shutil.copy('C:\\spam.txt', 'C:\\delicious')
'C:\\delicious\\spam.txt'
>>> shutil.copy('eggs.txt', 'C:\\delicious\\eggs2.txt')
'C:\\delicious\\eggs2.txt'
第一个 shutil.copy()
调用指定了一个文件夹作为目的地,将文件 C:\spam.txt
复制到了文件夹 C:\delicious下面。
第二个 shutil.copy()
调用也将文件C:\eggs.txt 复制到文件夹 C:\delicious,但为新文件提供了一个名字 eggs2.txt。
调用shutil.copytree()
将复制整个文件夹,以及它包含的子文件夹和文件。调用 shutil.copytree(source, destination)
,将路径 source
处的文件夹,包括它的所有文件和子文件夹,复制到路径 destination
处的文件夹。该函数返回一个字符串,是新复制的文件夹的路径。
>>> import shutil, os
>>> os.chdir('C:\\')
>>> shutil.copytree('C:\\bacon', 'C:\\bacon_backup')
'C:\\bacon_backup'
1.2 shutil.move()将文件和文件夹移动与改名
调用 shutil.move(source, destination)
,将路径 source
处的文件夹移动到路径destination
,并返回新位置的绝对路径的字符串。
如果 destination
指向一个文件夹,source
文件将移动到 destination
中,并保持原来的文件名:
>>> import shutil
>>> shutil.move('C:\\bacon.txt', 'C:\\eggs')
'C:\\eggs\\bacon.txt'
destination
路径也可以指定一个文件名。在下面的例子中,source
文件被移动并改名:
>>> shutil.move('C:\\bacon.txt', 'C:\\eggs\\new_bacon.txt')
'C:\\eggs\\new_bacon.txt'
前面两个例子都假设在 C:\目录下有一个文件夹 eggs。但是如果没有 eggs 文件夹,move()
就会将 bacon.txt 改名,变成名为 eggs 的文件:
>>> shutil.move('C:\\bacon.txt', 'C:\\eggs')
'C:\\eggs'
因为move()
在 C:\目录下找不到名为 eggs 的文件夹,所以假定 destination
指的是一个文件,而非文件夹。所以 bacon.txt 文本文件被改名为 eggs。
1.3 永久删除文件和文件夹
利用 os 模块中的函数,可以删除一个文件或一个空文件夹。但利用 shutil 模块,可以删除一个文件夹及其所有的内容。
-
用
os.unlink(path)
将删除 path 处的文件。 -
调用
os.rmdir(path)
将删除 path 处的文件夹。该文件夹必须为空,其中没有任何文件和文件夹。 -
调用
shutil.rmtree(path)
将删除 path 处的文件夹,它包含的所有文件和文件夹都会被删除。
删除具有.txt 扩展名的文件:
import os
for filename in os.listdir():
if filename.endswith('.txt'):
os.unlink(filename)
1.4 用 send2trash 模块安全地删除
Python 内建的 shutil.rmtree()
函数不可恢复地删除文件和文件夹,利用 send2trash
删除函数要安全得多,因为它会将文件夹和文件发送到计算机的垃圾箱或回收站,而不是永久删除它们。如果因程序缺陷而用send2trash
删除了某些你不想删除的东西,稍后可以从垃圾箱恢复。
>>> import send2trash
>>> baconFile = open('bacon.txt', 'a') # creates the file
>>> baconFile.write('Bacon is not a vegetable.')
25
>>> baconFile.close()
>>> send2trash.send2trash('bacon.txt')
2. 遍历目录树
假定你希望对某个文件夹中的所有文件改名,包括该文件夹中所有子文件夹中的所有文件。也就是说,你希望遍历目录树,处理遇到的每个文件。
以下例子程序,针对图 9-1 的目录树,使用了 os.walk()函数:
import os
for folderName, subfolders, filenames in os.walk('C:\\delicious'):
print('The current folder is ' + folderName)
for subfolder in subfolders:
print('SUBFOLDER OF ' + folderName + ': ' + subfolder)
for filename in filenames:
print('FILE INSIDE ' + folderName + ': '+ filename)
print('')
os.walk()
函数被传入一个字符串值,即一个文件夹的路径。你可以在一个 for循环语句中使用 os.walk()
函数,遍历目录树,os.walk()
在循环的每次迭代中,返回 3 个值:
1.当前文件夹名称的字符串。
2.当前文件夹中子文件夹的字符串的列表。
3.当前文件夹中文件的字符串的列表。
所谓当前文件夹,是指 for 循环当前迭代的文件夹。
运行该程序,它的输出如下:
The current folder is C:\delicious
SUBFOLDER OF C:\delicious: cats
SUBFOLDER OF C:\delicious: walnut
FILE INSIDE C:\delicious: spam.txt
The current folder is C:\delicious\cats
FILE INSIDE C:\delicious\cats: catnames.txt
FILE INSIDE C:\delicious\cats: zophie.jpg
The current folder is C:\delicious\walnut
SUBFOLDER OF C:\delicious\walnut: waffles
The current folder is C:\delicious\walnut\waffles
FILE INSIDE C:\delicious\walnut\waffles: butter.txt.
3. 用 zipfile 模块压缩文件
利用 zipfile 模块中的函数,Python 程序可以创建和打开或解压ZIP 文件。假定你有一个名为 example.zip 的 zip 文件,它的内容如下图所示:
3.1 读取 ZIP 文件
要读取 ZIP 文件的内容,首先必须创建一个 ZipFile
对象,要创建一个 ZipFile
对象,就调用 zipfile.ZipFile()
函数,向它传入一个字符串,表示.zip 文件的文件名。请注意,zipfile
是 Python 模块的名称,ZipFile()
是函数的名称:
>>> import zipfile, os
>>> os.chdir('C:\\') # move to the folder with example.zip
>>> exampleZip = zipfile.ZipFile('example.zip')
>>> exampleZip.namelist()
['spam.txt', 'cats/', 'cats/catnames.txt', 'cats/zophie.jpg']
>>> spamInfo = exampleZip.getinfo('spam.txt')
>>> spamInfo.file_size
13908
>>> spamInfo.compress_size
3828
>>> 'Compressed file is %sx smaller!' % (round(spamInfo.file_size / spamInfo
.compress_size, 2))
'Compressed file is 3.63x smaller!'
>>> exampleZip.close()
ZipFile
对象有一个 namelist()
方法,返回 ZIP 文件中包含的所有文件和文件夹的字符串的列表。这些字符串可以传递给 ZipFile
对象的 getinfo()
方法,返回一个关于特定文件的 ZipInfo
对象。ZipInfo
对象有自己的属性,诸如表示字节数的 file_size
和 compress_size
,它们分别表示原来文件大小和压缩后文件大小。
3.2 从 ZIP 文件中解压缩
ZipFile
对象的 extractall()
方法从 ZIP 文件中解压缩所有文件和文件夹,放到当前工作目录中:
>>> import zipfile, os
>>> os.chdir('C:\\') # move to the folder with example.zip
>>> exampleZip = zipfile.ZipFile('example.zip')
>>> exampleZip.extractall()
>>> exampleZip.close()
运行这段代码后,example.zip 的内容将被解压缩到 C:\。或者,你可以向extractall()
传递的一个文件夹名称,它将文件解压缩到那个文件夹,而不是当前工作目录。
ZipFile
对象的 extract()
方法从 ZIP 文件中解压缩单个文件:
>>> exampleZip.extract('spam.txt')
'C:\\spam.txt'
>>> exampleZip.extract('spam.txt', 'C:\\some\\new\\folders')
'C:\\some\\new\\folders\\spam.txt'
>>> exampleZip.close()
传递给 extract()
的字符串,必须匹配 namelist()
返回的字符串列表中的一个。或者你可以向 extract()
传递第二个参数,将文件解压缩到指定的文件夹,而不是当前工作目录。
3.3 创建和添加到 ZIP 文件
要创建你自己的压缩 ZIP 文件,必须以“写模式”打开
ZipFile 对象,即传入'w'
作为第二个参数(这类似于向 open()函数传入’w’,以写模式打开一个文本文件)。
write()
方法的第一个参数是一个字符串(文件路径),Python 会压缩该路径所指的文件,将它加到 ZIP 文件中。第二个参数是“压缩类型”参数,它告诉计算机使用怎样的算法来压缩文件。可以总是将这个值设置为 zipfile.ZIP_DEFLATED
(这指定了 deflate 压缩算法,它对各种类型的数据都很有效):
>>> import zipfile
>>> newZip = zipfile.ZipFile('new.zip', 'w')
>>> newZip.write('spam.txt', compress_type=zipfile.ZIP_DEFLATED)
>>> newZip.close()
这段代码将创建一个新的 ZIP 文件,名为 new.zip,它包含 spam.txt 压缩后的内容。
要记住,就像写入文件一样,写模式将擦除 ZIP 文件中所有原有的内容。如果只是希望将文件添加到原有的 ZIP 文件中,就要向 zipfile.ZipFile()
传入'a'
作为第二个参数,以添加模式打开 ZIP 文件。