选对压缩格式比写对代码更重要:zip适合跨平台快速打包,tar.gz兼顾通用性与压缩率,tar.xz适合高压缩归档,zstd在速度与压缩率间更平衡。

Python 中做文件压缩和解压,选对格式比写对代码更重要——不同场景下,zip、tar.gz、7z(需外部工具) 的性能差异可能达数倍。关键不在“能不能”,而在“快不快、占不占空间、跨不跨平台”。
压缩速度 vs 压缩率:按需取舍
压缩不是越高压越好,得看用途:
- zip:默认无压缩(STORE)或基础Deflate,打包快、解压快、Windows/macOS/Linux 原生支持,适合分发源码、日志归档、需要快速随机读取单个文件的场景;但压缩率一般,不支持多线程压缩(标准库层面)。
-
tar.gz(gzip):单线程压缩,中等速度,中等压缩率,POSIX 系统通用;适合备份整目录、CI/CD 中传输中间产物;注意:
tarfile模块默认不启用多线程,gzip 本身也不并行。 -
tar.xz(xz/lzma):压缩慢、解压稍慢,但压缩率显著更高(尤其文本类数据),适合长期归档、磁盘空间敏感场景;Python 标准库支持(
lzma模块),但内存占用略高。 -
7z / zstd(需第三方库):zstd 在压缩速度、解压速度、压缩率之间做了更好平衡,libzstd 绑定(如
pyzstd)可启用多线程;7z 需调用命令行,灵活性高但依赖外部环境。
Python 标准库实操要点
不用装包也能高效干活,但要注意这些细节:
- 用
zipfile.ZipFile时,指定compression=zipfile.ZIP_DEFLATED才真正压缩;用ZIP_STORED就是单纯打包,几乎零开销。 -
tarfile.open(..., "w:gz")内部调用 gzip.compress,无法控制压缩级别,默认是 6;想调高(如 9)需先用gzip.GzipFile手动封装流。 - 大文件压缩时,避免一次性读入内存:用
shutil.copyfileobj(src, dst, length=1024*1024)流式处理,防止 OOM。 - 解压路径要校验,防止 zip slip(如
../../etc/passwd):对ZipInfo.filename或TarInfo.name做os.path.abspath()+ 路径前缀检查。
真实场景对比建议
拿一个含 1000 个 Python 文件(约 20MB 源码)的目录测试(i7-11800H,Python 3.11):
立即学习“Python免费学习笔记(深入)”;
- 打包时间(秒):zip(0.18)< tar.gz(0.31)< tar.xz(1.9)< zstd(0.25,pyzstd + level=3)
- 压缩后体积:zip(7.2MB)> tar.gz(6.1MB)> zstd(5.8MB)> tar.xz(5.3MB)
- 解压时间(秒):zip(0.11)< zstd(0.13)< tar.gz(0.17)< tar.xz(0.28)
结论:日常开发打包用 zip;CI 产物传远端用 tar.gz 或 zstd;归档历史版本优先 tar.xz;追求极致解压速度且接受稍大体积,用 zip + STORE(仅打包)。
跨平台与兼容性避坑
别让压缩包在对方机器上打不开:
- Windows 用户收到
.tar.gz可能双击打不开,推荐附带说明或转成.zip;macOS 默认不带xz,.tar.xz需用户自行装 xz 工具。 - zip 文件注意中文路径:Python 3.7+ 默认用 UTF-8 存储文件名,但旧版 Windows 解压工具可能乱码;稳妥做法是统一用 ASCII 命名,或明确告知用户用 7-Zip / Bandizip 打开。
- tar 包在 Windows 上解压可能丢失权限或硬链接信息,若需完整 POSIX 属性(如 Docker 构建上下文),优先用
tar.gz并确保目标环境为 Linux。











