在 Python 中,我们可以使用 zipfile 模块来操作压缩文件。其中,压缩文件操作主要包括以下 3 种:
- 读取文件
- 解压文件
- 压缩文件
Python zipfile 读取文件
在 Python 中,我们可以使用 zipfile 模块的 ZipFile() 函数来读取压缩文件中的相关信息,例如文件大小、内部文件名等。
语法:
with zipfile.ZipFile(path) as zip:
……说明:
注意,zipfile 是 Python 模块 的名称,ZipFile() 是 zipfile 模块的一个函数(注意大小写)。
在当前项目中,有两个文件夹:src 和 dest,我们往 src 文件夹放入了一个压缩文件。整个项目结构如下图所示。

示例 1:列举文件名
import zipfile
with zipfile.ZipFile('src/list.zip') as zip:
print(zip.namelist())运行结果如下。
['A.txt', 'B.txt', 'C.txt']分析:
zipfile.ZipFile() 函数会返回一个 ZipFile 对象,该对象有一个 namelist() 方法。namelist() 方法可以返回一个列表,这个列表包含了压缩文件中所有的文件名。
示例 2:获取文件大小
import zipfile
with zipfile.ZipFile('src/list.zip') as zip:
info = zip.getinfo('A.txt')
print(info.file_size)运行结果如下。
12分析:
使用 ZipFile 对象的 getinfo() 方法会返回一个 ZipInfo 对象,这个对象有一个 file_size 属性,用于获取文件的大小,单位是 B(字节)。
Python zipfile 解压文件
在 zipfile 模块中,我们可以使用 ZipFile 对象的 extractall() 方法来将压缩文件进行解压。
语法:
with zipfile.ZipFile(path) as zip:
zip.extractall(dest)说明:
extractall() 方法中的参数 dest 是一个文件路径,表示你想要解压到哪个路径中去。
示例 3:解压文件
import zipfile
with zipfile.ZipFile('src/list.zip') as zip:
zip.extractall(r'dest')运行之后,项目结构如下图所示。

分析:
zip.extractall(r'dest') 表示解压到当前工作目录下的 dest 文件夹中,如果 dest 文件夹不存在,那么就会自动创建一个 dest 文件夹。
如果想要解压到当前工作目录下,只需要不传入任何参数就可以了,也就是直接调用:zip.extractall()。
Python zipfile 压缩文件
在 zipfile 模块中,我们可以使用 ZipFile 对象的 write() 方法来压缩文件。
语法:
import zipfile
with zipfile.ZipFile(path, 'w') as zip:
zip.write(文件名, compress_type=zipfile.ZIP_DEFLATED)说明:
想要压缩文件,必须以 “写模式” 打开 ZipFile 对象,也就是传入 'w' 作为第二个参数。这个类似于 open() 函数传入 'w',以写模式打开一个文本文件。如果希望将文件以 “追加” 的方式写入已有的 ZIP 文件中,我们可以传入 'a' 作为第二个参数。
compress_type = zipfile.ZIP_DEFLATED 指定了压缩的算法,小伙伴们可以将其看成固定参数即可。为了测试例子的效果,我们需要将当前目录结构重塑成如下图所示。

示例 4:压缩一个文件
import zipfile
with zipfile.ZipFile('dest/new.zip', 'w') as zip:
zip.write('src/A.txt', compress_type=zipfile.ZIP_DEFLATED)运行之后,项目结构变成如下图所示。

分析:
运行程序之后,我们可以看到 src 文件夹中的 A.txt 已经被压缩到 dest 文件夹中的 new.zip 中去了。如果想要压缩多个文件到一个压缩文件中去,也很简单,只需要以 “追加” 的方式多次写入就可以了,请看下面的示例。
示例 5:压缩多个文件
import zipfile
with zipfile.ZipFile('dest/new.zip', 'a') as zip:
zip.write('src/B.txt', compress_type=zipfile.ZIP_DEFLATED)
zip.write('src/C.txt', compress_type=zipfile.ZIP_DEFLATED)运行之后,项目结构变成如下图所示。

分析:
我们把 dest 文件夹中的 new.zip 手动解压一下,可以看到 src 中的 B.txt 和 C.txt 都被压缩到里面了。接下来清空 dest 文件夹,然后再去测试下面的例子。
示例 6:压缩文件夹(无效)
import zipfile
with zipfile.ZipFile('dest/new.zip', 'w') as zip:
zip.write(r'src', compress_type=zipfile.ZIP_DEFLATED)运行之后,项目结构变成如下图所示。

分析:
从这里可以看出来,src 文件夹已经被压缩到 dest 文件夹中的 new.zip 中去了。不过打开 new.zip 可以发现,zip 这个文件夹是空的。也就是说,我们不能直接压缩整个文件夹,而必须一个个文件地压缩。
想要把一个文件夹下的所有文件压缩,我们可以使用 os 模块的 walk() 函数来遍历所有文件,然后一一写入压缩文件中,请看下面例子。
示例 7:压缩文件夹(有效)
import os
import zipfile
# 获取所有文件的绝对路径
paths = []
for root, dirs, files in os.walk(r'src'):
for file in files:
# 智能拼接路径,防止跨平台报错
filepath = os.path.join(root, file)
paths.append(filepath)
# 写入压缩文件
with zipfile.ZipFile('dest/new.zip', 'w') as zip:
for path in paths:
zip.write(path, compress_type=zipfile.ZIP_DEFLATED)运行之后,项目结构变成如下图所示。

分析:
当再次打开 new.zip,此时会发现 src 中所有的文件都已经被成功压缩到里面去了。os.walk() 这个函数非常有用,一定要认真掌握。
