Python中如何递归复制目录且不覆盖目标目录?
解决shutil.copytree递归复制目录不覆盖目标内容的问题
shutil.copytree() 默认要求目标目录不存在,若强行用 dirs_exist_ok=True 参数允许目标存在,会覆盖同名文件。要实现合并式递归复制(不覆盖已有内容),可以用以下几种方案:
方法1:手动遍历目录,按需复制
遍历源目录的所有文件和子目录,仅当目标路径不存在时才执行复制,已存在的文件/目录直接跳过或递归合并。
import os import shutil def merge_copy(src_dir, dest_dir): # 确保目标父目录存在 os.makedirs(dest_dir, exist_ok=True) for item_name in os.listdir(src_dir): src_item = os.path.join(src_dir, item_name) dest_item = os.path.join(dest_dir, item_name) if os.path.isdir(src_item): # 递归处理子目录 merge_copy(src_item, dest_item) else: # 仅复制不存在的文件 if not os.path.exists(dest_item): shutil.copy2(src_item, dest_item) print(f"已复制: {src_item} -> {dest_item}") else: print(f"跳过已存在文件: {dest_item}") # 使用示例 merge_copy("source_dir_1", "target_dir") merge_copy("source_dir_2", "target_dir")
方法2:自定义copytree的复制逻辑
利用 shutil.copytree() 的 copy_function 参数,自定义文件复制行为,跳过已存在的文件;配合 dirs_exist_ok=True 实现目录合并。
import os import shutil def safe_copy(src, dst): # 目标不存在时才复制,保留文件元数据 if not os.path.exists(dst): shutil.copy2(src, dst) else: print(f"跳过已存在文件: {dst}") def merge_copytree(src_dir, dest_dir): shutil.copytree( src_dir, dest_dir, copy_function=safe_copy, dirs_exist_ok=True ) # 使用示例 merge_copytree("source_dir_1", "target_dir") merge_copytree("source_dir_2", "target_dir")
方法3:用pathlib简化路径操作(Python3.4+)
借助pathlib的面向对象API,更简洁地处理路径遍历和判断逻辑,核心逻辑和方法1一致。
from pathlib import Path import shutil def merge_copy_pathlib(src_dir, dest_dir): src_path = Path(src_dir) dest_path = Path(dest_dir) dest_path.mkdir(parents=True, exist_ok=True) for item in src_path.iterdir(): dest_item = dest_path / item.name if item.is_dir(): merge_copy_pathlib(item, dest_item) else: if not dest_item.exists(): shutil.copy2(item, dest_item) print(f"已复制: {item} -> {dest_item}") else: print(f"跳过已存在文件: {dest_item}") # 使用示例 merge_copy_pathlib("source_dir_1", "target_dir") merge_copy_pathlib("source_dir_2", "target_dir")
内容的提问来源于stack exchange,提问作者tclemment
相关产品推荐
相关产品推荐

