Python 里”移动整个目录”或”把文件全复制到另一处”这类操作,全部靠 shutil。列几个最常用的模板。
移动整个目录
99% 场景直接:
import shutil
shutil.move(r"C:\source_dir", r"D:\target_dir")
行为:
- 目标不存在 → 直接改名/移动
- 目标已存在 → 源被移到
目标\源目录名 - 同盘 是秒移(本质是 rename)
- 跨盘 会退化成复制 + 删除
想强制覆盖已有目标:
import os, shutil
src = r"C:\source_dir"
dst = r"D:\target_dir\source_dir"
if os.path.exists(dst):
shutil.rmtree(dst)
shutil.move(src, dst)
复制整个目录(含子目录)
Python 3.8+:
import shutil
shutil.copytree(
r"C:\source_dir",
r"D:\target_dir",
dirs_exist_ok=True, # 目标已存在时合并写入
)
会连带子目录、文件属性一起复制。
只复制当前目录里的文件(跳过子目录)
import os, shutil
src = r"C:\source_dir"
dst = r"D:\target_dir"
os.makedirs(dst, exist_ok=True)
for name in os.listdir(src):
s = os.path.join(src, name)
if os.path.isfile(s):
shutil.copy2(s, os.path.join(dst, name))
copy2 会保留 mtime、权限,比 copy 更完整。
只复制某类文件
import os, shutil
for name in os.listdir(src):
if name.endswith(".txt"):
shutil.copy2(
os.path.join(src, name),
os.path.join(dst, name),
)
递归复制文件(扁平化,不保留目录结构)
import os, shutil
for root, _, files in os.walk(src):
for f in files:
shutil.copy2(os.path.join(root, f), os.path.join(dst, f))
注意同名文件会互相覆盖,要保结构就直接 copytree。
用 pathlib 版本(更现代)
from pathlib import Path
import shutil
src = Path(r"D:\A\deep\folder")
dst = Path(r"D:\B\deep\folder")
if dst.exists():
shutil.rmtree(dst)
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copytree(src, dst)
Path 的 parent / mkdir(parents=True) 组合特别适合处理”目标父目录还没创建”的情况。
不要用 os.rename
os.rename(src, dst)
- 跨磁盘直接报错
- 不能覆盖已有目录
除非明确是”同盘、无冲突”,否则直接上 shutil.move。
一句话总结
移动用 shutil.move,整目录复制用 shutil.copytree(dirs_exist_ok=True)。其它场景在这两个基础上按需组合。
