当 os 模块提供的文件操作功能不够用,或者你需要更快地完成“复制整个目录树”“打包压缩”这种复杂任务时,就该 shutil 模块登场了。它是一套高级文件操作工具,内部封装了操作系统底层调用,用起来比手动读文件、写文件更省心也更安全。
文件与目录的复制
shutil.copy(src, dst)
复制文件内容(不包括元数据),dst 可以是目录或完整文件名。相当于把文件拷贝一份。
import shutil
shutil.copy('source.txt', 'backup.txt') # 复制到文件
shutil.copy('source.txt', '/backup/') # 复制到目录,保持原名
shutil.copy2(src, dst)
和 copy() 类似,但会尽量保留文件的元数据(如修改时间、创建时间),是更完整的文件复制。
shutil.copytree(src, dst)
递归复制整个目录树,把 src 目录下的所有文件和子目录全部复制到 dst 下。
shutil.copytree('project/', 'project_backup/')
常用参数:
dirs_exist_ok=True(Python 3.8+):目标目录存在时不报错,会覆盖同名文件。ignore=shutil.ignore_patterns('.pyc', 'tmp'):复制时忽略某些文件。
shutil.copyfileobj(fsrc, fdst)
在两个文件对象之间复制内容,适合处理大文件或流式数据。
文件与目录的移动与删除
shutil.move(src, dst)
移动文件或目录,也可以用来重命名。如果 dst 是目录,则将 src 移入该目录;否则等同于重命名。
shutil.move('old_name.txt', 'new_name.txt') # 重命名
shutil.move('report.pdf', '/archive/') # 移动到目录
shutil.rmtree(path)
递归删除整个目录树(相当于 rm -rf),不是只删空目录,要小心使用。
参数 ignore_errors=True 可忽略删除错误;onerror 可自定义处理错误函数。
压缩与打包
shutil.make_archive() 和 shutil.unpack_archive() 是两大核心,封装了多种压缩格式,一行代码就能把目录打包成压缩包。
shutil.make_archive(base_name, format, root_dir)
将 root_dir 下的内容打包并压缩,生成的文件名为 base_name 加上格式后缀。
# 把 my_project 目录打包成 my_project.zip
shutil.make_archive('my_project', 'zip', 'my_project')
# 生成 my_project.tar.gz
shutil.make_archive('my_project', 'gztar', 'my_project')
支持的格式:zip、tar、gztar(tar.gz)、bztar(tar.bz2)、xztar(tar.xz)。
注意:打包的是 root_dir 目录下的内容,而不是目录本身(除非你设置 base_dir 参数)。
shutil.unpack_archive(filename, extract_dir)
解压任意支持的压缩包到指定目录。
shutil.unpack_archive('my_project.zip', 'extracted/')
它会根据文件后缀自动识别格式,不需要手动指定。
shutil.get_archive_formats()
返回当前系统支持的压缩格式列表,写入/读取都可用它来确认可用的格式。
其他实用函数
shutil.disk_usage(path)
获取路径所在磁盘的容量信息,返回 (总容量, 已用, 剩余),单位字节。
total, used, free = shutil.disk_usage('/')
print(f"剩余空间: {free // (1024**3)} GB")
shutil.which(cmd)
在系统 PATH 中查找可执行文件的完整路径,类似 Linux 的 which 命令。
shutil.which('python') # 返回类似 '/usr/bin/python' 或 None
shutil.chown(path, user, group)
修改文件或目录的所属用户和组(仅在 Linux/macOS 下有效)。
shutil 模块的设计目标就是让常见的系统管理类操作变得简单直接,减少手写底层调用的出错可能。在写自动化脚本、构建工具、备份程序时,你会经常用到它。