前言
在 Python 项目里处理压缩包,绕不开这几个老问题:
- 标准库
zipfile/tarfile能力太弱,不支持 7z、RAR、ISO、VHDX、DMG等格式; py7zr是纯 Python 实现,大文件慢、内存占用高、复杂压缩方案兼容性差;- 用
subprocess调 7z.exe / 7za,要自己管二进制、处理进程、日志编码、跨平台打包,后端服务里还容易踩命令注入和僵尸进程的坑; - 想用 zstd、brotli、lz4 这些新编码,要么再找一套库,要么手动拼 plugin。
今天分享我开源的pybit7z—— 基于 bit7z 用 pybind11 封装的 Python 绑定库,直接对接 7-zip 底层 SDK,不拉起独立进程,wheel 里还自带 zstd / brotli / lz4 / lz5 / lizard / flzma2 / bsc / zpaq 外部 codec 插件,开箱即用。
✨ 核心优势
- C++ 原生内核:bit7z + 7-zip codec,和命令行 7z 同源能力;对比纯 Python 的 py7zr,大文件压缩解压速度优势明显;
- 60+ 格式读取:rar/rar5、iso、cab、chm、nsis、vmdk、vhdx、dmg、squashfs、ext、ntfs、gpt、uefic……磁盘镜像、安装包、固件包都能直接读;
- 7 种格式写入:7z / zip / tar / gzip / bzip2 / xz / wim;
- 自带外部 Codec 插件:zstd、brotli、lz4、lz5、lizard、flzma2、bsc、zpaq 全部打包在 wheel 里,无需额外安装;
- 内存级操作:压缩/解压直接到
bytesbuffer,适合网络传输、API 响应、流式处理; - 嵌套归档读取:
BitNestedArchiveReader直接打开 tar.gz 里的 tar 包; - 完整元数据:条目数、文件夹数、CRC、通配符匹配、根目录探测、属性可用性检查;
- 加密与高级压缩:7z AES-256 + 头加密、固实压缩、分卷、自定义字典/词大小、多线程;
- CLI 命令行工具:
pybit7z一条命令搞定 compress/extract/list/test/info/update; - 懒加载库:
Bit7zLibraryLoader显式 load/try_load/unload,适合探测环境、延迟加载; - 跨平台:Windows / macOS / Linux(含 musllinux),Python 3.9+,预编译 wheel。
一句话区分:
- py7zr:纯 Python,只主打 7z,慢、格式少;
- subprocess + 7za:外部进程,运维和打包麻烦;
- pybit7z:库级调用 7z codec + 外部插件,C++ 内核,全格式、高性能、带 CLI。
📦 安装
pip install pybit7z🚀 Python API 调用示例
所有操作都需要一个Bit7zLibrary实例。用lib7zip_context()上下文管理器,会自动定位 wheel 里打包的lib7zip:
import pybit7z with pybit7z.lib7zip_context() as lib: ...1. 加载外部插件(zstd / brotli / lz4 等)
注意:lib7zip_context()不会自动加载外部 codec 插件。需要手动调load_plugins(),传入插件目录;每个目录会先扫Codecs/子目录,再扫Formats/子目录。
import pybit7z with pybit7z.lib7zip_context() as lib: # 加载 wheel 自带的插件(zstd/brotli/lz4/lz5/lizard/flzma2/bsc/zpaq) lib.load_plugins([pybit7z.default_plugin_dir()]) # 也可以传多个目录,累加加载 # lib.load_plugins([ # pybit7z.default_plugin_dir(), # "/opt/7z/plugins", # 自定义 plugin 目录 # "/usr/lib/7zip/Codecs", # 系统 7z 安装目录 # ])加载之后,压缩时就能直接用 zstd、brotli 等格式了。
2. 解压归档
import pybit7z try: with pybit7z.lib7zip_context() as lib: extractor = pybit7z.BitFileExtractor(lib, pybit7z.FormatSevenZip) # 解压整个归档到目录 extractor.extract("archive.7z", "./out_dir/") # 只解压匹配的单个文件 extractor.extract_matching("archive.7z", "report.pdf", "./out_dir/") # 解压归档里第一个文件到内存 buffer(不落地) buffer: bytes = extractor.extract("archive.7z") # 解压加密包 extractor.set_password("123456") extractor.extract("secret.7z", "./out_dir/") except pybit7z.BitException as e: print(f"解压失败: {e}")单归档对象方式(适合边读边处理):
import pybit7z with pybit7z.lib7zip_context() as lib: arc = pybit7z.BitArchiveReader(lib, "data.tar.gz", pybit7z.FormatGZip) arc.test() # 测试完整性 arc.extract_to("./out/") # 解压3. 压缩归档
import pybit7z try: with pybit7z.lib7zip_context() as lib: compressor = pybit7z.BitFileCompressor(lib, pybit7z.FormatSevenZip) files = ["a.jpg", "b.pdf"] # 基础压缩成 zip compressor.compress(files, "out.zip") # 自定义归档内路径(重命名/改目录结构) files_map = { "a.jpg": "photos/a.jpg", "b.pdf": "docs/b.pdf", } compressor.compress(files_map, "out2.zip") # 压缩整个目录 compressor.compress_directory("./data/", "data.7z") # 加密压缩(7z 支持头加密) compressor.set_password("mypwd") compressor.compress_files(files, "protected.7z") # 追加模式:往已有归档里加文件 compressor.set_update_mode(pybit7z.UpdateMode.Append) compressor.compress_files(["new.txt"], "existing.zip") # 压缩单个文件到内存 buffer with pybit7z.lib7zip_context() as lib: c2 = pybit7z.BitFileCompressor(lib, pybit7z.FormatBZip2) buf: bytes = c2.compress_file("hello.txt") except pybit7z.BitException as e: print(f"压缩失败: {e}")单归档对象方式:
import pybit7z with pybit7z.lib7zip_context() as lib: arc = pybit7z.BitArchiveWriter(lib, pybit7z.FormatSevenZip) arc.add_file("file.txt") arc.add_directory("./docs/") arc.compress_to("output.7z")4. 读取归档元数据
import pybit7z with pybit7z.lib7zip_context() as lib: arc = pybit7z.BitArchiveReader(lib, "archive.7z", pybit7z.FormatSevenZip) # 归档级属性 print("条目数:", arc.items_count()) print("文件夹数:", arc.folders_count()) print("文件数:", arc.files_count()) print("原始大小:", arc.size()) print("压缩后大小:", arc.pack_size()) # 遍历每个条目 for item in arc: print(item.index(), item.name(), item.is_dir(), item.size(), item.crc()) # 通配符匹配:只拿 .txt 文件 txt_files = list(arc.items_matching("*.txt")) # 所有条目的共同根目录(没有则为空串) print("根目录:", arc.root_folder()) # 检查某个条目是否支持某属性 if arc.item_has_property(0, pybit7z.BitProperty.Size): size = arc.item_at(0).item_property(pybit7z.BitProperty.Size) # 原生名称 / 原始路径 item = arc.item_at(0) print("native name:", item.native_name()) print("raw path:", item.raw_path())5. 嵌套归档读取(tar.gz 里的 tar)
import pybit7z with pybit7z.lib7zip_context() as lib: # 第一步:打开外层 tar.gz(GZip)归档 outer_arc = pybit7z.BitArchiveReader(lib, "archive.tar.gz", pybit7z.FormatGZip) # 第二步:传入外层 reader,打开内部嵌套 tar,中间文件不落地 nested_arc = pybit7z.BitNestedArchiveReader(lib, outer_arc, pybit7z.FormatTar) # 直接解压内部 tar 里的内容 nested_arc.extract_to("./out/")6. 懒加载库 / 环境探测
如果你想在不抛异常的前提下探测 7-zip 是否可用,或者延迟加载自定义编译的 lib7zip:
import pybit7z with pybit7z.loader_context() as loader: # try_load 失败不抛异常,适合服务启动时探测 if loader.try_load(pybit7z.default_lib7zip()): lib = loader.library() # 正常使用 lib ... else: print("lib7zip 不可用,跳过压缩功能") # 退出 with 块自动 unload💻 命令行示例(CLI)
pybit7z 自带pybit7z命令行工具,日常归档操作不用写 Python:
# 压缩文件/目录 pybit7z compress file.txt -o out.7z pybit7z compress ./data/ -o out.zip -f zip -l Ultra # 解压 pybit7z extract archive.7z -o out_dir/ pybit7z decompress archive.tar.gz -o out_dir/ # 列出内容 / 测试完整性 pybit7z list archive.7z pybit7z test archive.7z # 查看当前 build 支持的所有格式和 codec pybit7z infoCLI 加载外部插件
CLI 会自动加载 wheel 自带的插件。如果要从自定义目录加载额外插件(比如系统装的 7z plugin),用--plugin-dir,可重复传入:
# 用自定义 zstd plugin 压出 .zst pybit7z compress file.txt -o out.zst --plugin-dir /path/to/plugins # 多个 plugin 目录 pybit7z compress file.txt -o out.7z \ --plugin-dir /opt/7z/Codecs \ --plugin-dir ~/.local/share/7zip/plugins更多选项:密码、压缩方法、线程数、分卷、过滤、stdin/stdout 管道等,跑
pybit7z --help看完整列表。
🧩 支持格式与外部插件
可写入格式(7种)
7zziptargzipbzip2xzwim
可读取格式(60+)
7zziptargzipbzip2xzzlzmaapfsarjcabchmcpiocramfsdmgelfextfatgpthfsisolzhmachombrntfspecoffppmdqcowrarrar5rpmsquashfsswfueficvdivhdvhdxvmdkxarudfwimnsis……
自带外部插件(bundled)
| 插件 | 类型 | 说明 |
|---|---|---|
| zstd | format + codec | Zstandard 压缩 |
| brotli | format + codec | Brotli 压缩 |
| lz4 | format + codec | LZ4 压缩 |
| lz5 | format + codec | LZ5 压缩 |
| lizard | format + codec | Lizard (LZ5) 压缩 |
| flzma2 | codec | Fast LZMA2 |
| bsc | codec | BSC (libbsc) 压缩 |
| zpaq | codec | ZPAQ 压缩 |
这些插件直接打包在 wheel 的Codecs/和Formats/子目录里,Python 里调lib.load_plugins([pybit7z.default_plugin_dir()])或 CLI 加--plugin-dir即可,无需单独安装。
🎯 适合哪些场景
- 后端服务:自动备份、日志归档、文件导出接口,直接内存压缩成 bytes 返回,不落地;
- 运维脚本:批量解析 ISO、VHDX、RAR、DMG、squashfs 等各类归档;
- 嵌入式 / 固件开发:读 NSIS 安装包、UEFI 镜像、ext 镜像、固件升级包;
- 桌面工具:PySide / Flet 应用里带压缩功能,不用绑 7z.exe;
- 数据处理:大量文件高速打包、加密分发、zstd 流式压缩;
- 逆向 / 取证:直接读 PE、COFF、MBR、GPT、VMDK 等镜像格式。
📌 项目地址
- PyPI:Client Challenge
- 在线文档:pybit7z documentation
- GitHub:https://github.com/msclock/pybit7z
欢迎 Star、提 Issue、PR,使用问题评论区留言。
📝 写在最后
如果你长期被 Python 压缩库的各种坑折磨,想要一个稳定、高速、格式全、带外部 codec 插件、API 干净、还有 CLI的 7z 库,pybit7z 值得一试。它不是套一层命令行,而是库级原生集成 bit7z + 7-zip SDK,在服务端、自动化脚本、嵌入式镜像处理场景下优势非常明显。
觉得有用欢迎点赞👍收藏⭐关注,后续会更新 pybit7z 进阶教程:zstd 多线程压缩调优、自定义 plugin 编译、和 FastAPI 结合做流式压缩接口等。