>>> from env_helper import info; info()
页面更新时间: 2024-01-19 21:43:30
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-17-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

3.5. zipfile 模块压缩文件

你可能熟悉ZIP文件(带有.zip文件扩展名),它可以包含许多其他文件的压缩内容。 压缩一个文件会减少它的大小,这在因特网上传输时很有用。 因为一个ZIP文件可以包含多个文件和子文件夹,所以它是一种很方便的方式,将多个文件打包成一个文件。 这个文件叫做“归档文件”,然后可以用作电子邮件的附件,或其他用途。

利用 zipfile 模块中的函数,Python程序可以创建和打开(或解压)ZIP文件。 假定你有一个名为 new.zip 的文件。

可以从 http://nostarch.com/automatestuff/ 下载这个ZIP文件,或者利用计算机上 已有的一个ZIP文件,接着完成下面的操作。

3.5.1. 读取 ZIP 文件

要读取ZIP文件的内容,首先必须创建一个 ZipFile 对象 (请注意大写首字母Z和F)。 ZipFile 对象在概念上与 File 对象相似:它们是一些值,程序通过它们与文件打交道。 要创建一个ZipFile 对象,就调用 zipfile.ZipFile() 函数,向它传入一个字符串,如 .zip 文件的文件名。 请注意, zipfile 是Python模块的名称, ZipFile() 是函数的名称。

例如,在交互式环境中输入以下代码:

>>> import zipfile, os
>>> # move to the folder with example.zip
>>> # os.chdir('.')
>>> exampleZip = zipfile.ZipFile('new.zip')
>>> exampleZip.namelist()
['new/', 'new/hello1.txt', 'new/hello2.txt']
>>> spamInfo = exampleZip.getinfo('new/hello1.txt')
>>> spamInfo.file_size
13
>>> spamInfo.compress_size
15
>>> 'Compressed file is {}x smaller!'.format(round(spamInfo.file_size / spamInfo.compress_size, 2))
'Compressed file is 0.87x smaller!'
>>> exampleZip.close()

ZipFile 对象有一个 namelist() 方法, 返回ZIP文件中包含的所有文件和文件夹的字符串的列表。 这些字符串可以传递给 ZipFile 对象的 getinfo() 方法, 返回一个关于特定文件的 Ziplnfo 对象。 Ziplnfo 对象有自己的属性,诸如表示字节数的 file_sizecompress_size , 它们分别表示原来文件大小和压缩后文件大小。 ZipFile 对象表不整个归档文件, 而 ZipInfo 对象则保存该归档文件中每个文件的有用信息。

'Compressed file is %sx smaller!' % (round(spamInfo.file_size / spamInfo.compress_size, 2))的命令计算出 example.zip 压缩的效率, 用压缩后文件的大小除以原来文件的大小,并以%s字符串格式打印出这一信息。

3.5.2. 从 ZIP 文件中解压缩

ZipFile 对象的 extractall() 方法从 ZIP 文件中解压缩所有文件和文件夹,放到当前工作目录中。

>>> import zipfile, os
>>> os.chdir('.') # move to the folder with example.zip
>>> exampleZip = zipfile.ZipFile('new.zip')
>>> exampleZip.extractall('xx_out')
>>> exampleZip.close()

运行这段代码后, example.zip 的内容将被解压缩到 xx_out 文件夹。 或者,如果 extractall() 没有使用参数,会解压缩到当前文件夹。 如果传递给 extractall() 方法的文件夹不存在,它会被创建。

ZipFile 对象的 extract() 方法从ZIP文件中解压缩单个文件。 继续交互式环境中的例子:

>>> exampleZip = zipfile.ZipFile('new.zip')
>>> exampleZip.extract('new/hello1.txt')
'/home/bk/book-jubook/python/jubook_python/pt04_essential/ch03_file/new/hello1.txt'
>>> exampleZip.extract('new/hello2.txt','.')
>>> exampleZip.close()

传递给 extract() 的字符串,必须匹配 namelist()返回的字符串列表中的一个。 或者,你可以向 extract() 传递第二个参数,将文件解压缩到指定的文件夹,而不是当前工作目录。 如果第二个参数指定的文件夹不存在, Python 就会创建它。 extract() 的返回值是被压缩后文件的绝对路径。

3.5.3. 创建和添加到ZIP文件

要创建你自己的压缩ZIP文件,必须以“写模式”打开 ZipFile 对象, 即传入 'w'作为第二个参数(这类似于向 open()函数传入 'w' 以写模式打开一个文本文件)。

如果向 ZipFile 对象的 write() 方法传入一个路径,Python就会压缩该路径所指的文件,将它加到ZIP文件中。 write() 方法的第一个参数是一个字符串,代表要添加的文件名。 第二个参数是“压缩类型”参数,它告诉计算机使用怎样的算法来压缩文件。 可以总是将这个值设置为 zipfile.ZIP_DEFLATHD (这指定了 deflate 压缩算法,它对各种类型的数据都很有效)。 在交互式环境中输入以下代码:

>>> import zipfile
>>> newZip = zipfile.ZipFile('xx_new2.zip', 'w')
>>> newZip.write('chapter.ipynb',compress_type=zipfile.ZIP_DEFLATED)
>>> newZip.close()

这段代码将创建一个新的ZIP文件,名为 xx_new.zip ,它包含 chapter.ipynb 压缩后的内容。

要记住,就像写入文件一样,写模式( w )将擦除ZIP文件中所有原有的内容。 如果只是希望将文件添加到原有的 ZIP 文件中,就要向 zipfile.ZipFile() 传入 'a' 作为第二个参数, 以添加模式打开 ZIP 文件。