Python案例实战指南(附完整代码)
目录导读
- 为什么要用Python压缩文件夹?
- 核心库选择:zipfile与shutil的对比分析
- 实战案例一:基础文件夹压缩(zip格式)
- 实战案例二:带密码保护与分卷压缩的高级方案
- 实战案例三:跨平台兼容性与异常处理优化
- 常见问题与解决方案(Q&A)
- SEO优化建议与性能调优技巧
为什么要用Python压缩文件夹?
在日常开发与运维工作中,我们经常需要批量处理文件:备份项目代码、归档日志文件、传输数据包等,手动右键压缩不仅效率低下,而且难以在自动化流程中集成,Python作为脚本语言之王,提供了zipfile、shutil、tarfile、py7zr等多个库来满足不同压缩需求。

核心优势:
- 自动化:结合定时任务(如cron)实现定期备份
- 跨平台:Windows/Linux/macOS代码一致
- 灵活扩展:支持密码、分卷、多线程等高级特性
- 节省空间:可自定义压缩级别与文件过滤规则
核心库选择:zipfile与shutil的对比分析
| 特性 | zipfile | shutil.make_archive | tarfile |
|---|---|---|---|
| 适用场景 | 精细控制单个文件 | 快速打包整个目录 | Linux环境兼容 |
| 密码支持 | 支持(需第三方库) | 不支持 | 支持 |
| 压缩格式 | zip | zip,tar,gztar,bztar | tar.gz,tar.bz2 |
| 层级控制 | 手动遍历文件 | 自动递归 | 自动递归 |
| 性能 | 中等 | 高(C底层优化) | 高 |
对于初学者,shutil.make_archive是最快捷的方式;如果需要密码保护或文件过滤,推荐zipfile;在Linux服务器上,tarfile是标准选择。
实战案例一:基础文件夹压缩(zip格式)
import os
import zipfile
from pathlib import Path
def compress_folder_to_zip(source_folder, output_zip):
"""
压缩整个文件夹为zip文件
:param source_folder: 源文件夹路径
:param output_zip: 输出zip文件路径
"""
source_folder = Path(source_folder)
with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
for file_path in source_folder.rglob('*'):
if file_path.is_file():
# 在zip中保持相对路径
arcname = file_path.relative_to(source_folder.parent)
zf.write(file_path, arcname)
# 使用示例
compress_folder_to_zip('/home/user/project', 'backup.zip')
关键点:
rglob('*')递归获取所有文件ZIP_DEFLATED启用压缩(默认为存储模式)relative_to保留文件夹层级结构
实战案例二:带密码保护与分卷压缩的高级方案
许多企业需要加密传输文件,我们利用pyzipper库实现AES-256加密:
import pyzipper
def encrypt_folder(source_folder, output_zip, password):
"""
加密压缩文件夹(AES-256)
"""
with pyzipper.AESZipFile(output_zip, 'w', encryption=pyzipper.WZ_AES) as zf:
zf.setpassword(password.encode('utf-8'))
for root, dirs, files in os.walk(source_folder):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, source_folder)
zf.write(file_path, arcname)
# 使用
encrypt_folder('data', 'encrypted_backup.zip', 'MySecurePassword2024')
分卷压缩实现(利用split_zipfile库或手动分割):
import zipfile
import math
def split_zip(source_folder, output_prefix, max_size_mb=100):
"""分卷压缩:每个卷最大100MB"""
max_bytes = max_size_mb * 1024 * 1024
current_size = 0
part_num = 0
zf = None
for root, dirs, files in os.walk(source_folder):
for file in files:
file_path = os.path.join(root, file)
file_size = os.path.getsize(file_path)
# 如果当前卷超过限制,创建新卷
if zf is None or current_size + file_size > max_bytes:
if zf:
zf.close()
part_num += 1
part_name = f"{output_prefix}.part{part_num}.zip"
zf = zipfile.ZipFile(part_name, 'w', zipfile.ZIP_DEFLATED)
current_size = 0
arcname = os.path.relpath(file_path, source_folder)
zf.write(file_path, arcname)
current_size += file_size
if zf:
zf.close()
print(f"分卷完成,共{part_num}个文件")
实战案例三:跨平台兼容性与异常处理优化
import logging
import sys
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def safe_compress(folder_path, output_path, exclude_ext=None):
"""
安全压缩:自动处理路径分隔符、权限问题、中文文件名
:param folder_path: 源文件夹
:param output_path: 输出zip
:param exclude_ext: 排除的文件扩展名列表 ['tmp', 'log']
"""
try:
folder_path = Path(folder_path).resolve()
if not folder_path.exists():
raise FileNotFoundError(f"源文件夹不存在: {folder_path}")
# Windows路径兼容转换
output_path = output_path.replace('\\', '/')
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zf:
for file_path in folder_path.rglob('*'):
if file_path.is_file():
# 跳过排除文件
if exclude_ext and file_path.suffix.lstrip('.') in exclude_ext:
continue
# 使用UTF-8编码文件名避免乱码
arcname = file_path.relative_to(folder_path.parent)
arcname = str(arcname).encode('utf-8').decode('utf-8')
try:
zf.write(file_path, arcname)
logging.info(f"已添加: {arcname}")
except PermissionError:
logging.warning(f"跳过无权限文件: {file_path}")
logging.info(f"压缩完成: {output_path} (大小: {os.path.getsize(output_path)/1024:.1f} KB)")
return True
except Exception as e:
logging.error(f"压缩失败: {str(e)}")
if os.path.exists(output_path):
os.remove(output_path) # 清理不完整的压缩文件
return False
# 使用
safe_compress('/var/log/myapp', 'logs_backup.zip', exclude_ext=['tmp', 'swp'])
常见问题与解决方案(Q&A)
Q1: 压缩后的文件在Windows下乱码怎么办?
A: 确保使用zipfile.ZipFile时指定utf-8编码,如果使用shutil.make_archive,请在Windows系统上安装chardet库并检测原系统编码,推荐统一使用pathlib处理路径。
Q2: 如何只压缩特定类型的文件(如只压缩.py和.txt)? A: 在遍历文件时添加过滤条件:
if file_path.suffix in ['.py', '.txt', '.md']:
zf.write(file_path, arcname)
Q3: 压缩超大文件夹(超过4GB)时出错?
A: zip格式有4GB文件大小限制(ZIP64格式可突破),建议:1)使用zipfile.ZIP64模式;2)改用tar.gz格式;3)分卷压缩,注意Python3.4+默认支持ZIP64。
Q4: 压缩速度太慢怎么优化?
A: 1)使用threading多线程并行压缩;2)降低压缩级别(ZIP_STORED仅存储不压缩);3)先用os.scandir快速扫描文件;4)对大文件使用流式处理而非一次性加载。
Q5: 能否在压缩中删除原文件? A: 可以在压缩成功后添加:
import shutil shutil.rmtree(source_folder) # 谨慎使用
SEO优化建议与性能调优技巧
代码优化要点:
- 使用
pathlib替代os.path,代码更简洁且跨平台 - 善用生成器表达式减少内存占用
- 对大目录使用
os.scandir代替os.listdir - 压缩级别设为
ZIP_DEFLATED(默认)平衡速度与大小 - 缓存
os.path.getsize结果避免重复调用
搜索引擎优化小贴士:
- 文章中的代码块使用
<pre>标签并设置lang="python" - 外部链接使用
nofollow属性(本文已按要求替换所有域名指向示例) - 添加结构化数据标记(FAQ Schema)提升搜索结果展示
- 核心关键词自然分布在H2/H3标题中(如"Python压缩文件夹")
扩展阅读建议:
- 官方文档:Python
zipfile模块文档 - 安全实践:压缩路径遍历攻击防护(避免等危险路径)
- 替代方案:使用7-Zip的命令行接口通过
subprocess实现更高压缩率
本文从基础到高级,系统讲解了使用Python压缩本地文件夹的多种方案,从最简单的
shutil.make_archive一行代码,到支持AES-256加密与分卷压缩的企业级实现,再到跨平台异常处理的完整解决方案,无论你是需要自动化备份的运维工程师,还是搭建云存储工具的开发者,这些案例都能直接应用于实际生产环境,选择哪种方案取决于你的具体场景:快速开发用shutil,安全加密用pyzipper,Linux服务器首选tarfile,动手实践时,不妨从我们的安全压缩函数开始,逐步添加到你的自动化脚本中。