You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本递归选择性复制文件夹问题求助(含代码)

解决Python递归复制目录并忽略指定文件的问题

你的代码目前存在几个核心问题,导致无法实现递归复制并保留目录结构的需求:

  1. 仅遍历了源目录的一级内容,没有递归处理子目录
  2. 过滤逻辑和需求相反(当前是排除.bmp文件,而你需要忽略.py和.log)
  3. 使用copy_file会把所有文件直接放到目标目录根,完全丢失原有的子目录结构

其实Python的shutil模块已经提供了完美的解决方案——shutil.copytree,它原生支持递归复制目录、保留目录结构,还能通过ignore参数轻松实现文件过滤。下面给你两种实现方式:

方式一:快速实现(基础版)

适合只需要完成复制和简单日志记录的场景:

import os
import shutil
from datetime import datetime

# 配置路径
src = "E:\\Test\\src"
dest = "E:\\Test\\dest"
log_path = "E:\\Test\\upgrade.log"

def recursive_copy_with_ignore():
    # 定义要忽略的文件模式:匹配所有.py和.log文件
    ignore_patterns = shutil.ignore_patterns("*.py", "*.log")
    
    try:
        # copytree会自动递归复制所有子目录,保留原结构
        # dirs_exist_ok=True 允许目标目录已存在(Python3.8+支持)
        shutil.copytree(src, dest, ignore=ignore_patterns, dirs_exist_ok=True)
        
        # 记录成功日志
        success_log = f"{datetime.now().strftime('%d/%m/%Y %H:%M:%S')} 递归复制完成:源目录 {src} → 目标目录 {dest}\n"
        with open(log_path, "a") as log_file:
            log_file.write(success_log)
        print(success_log)
    except Exception as e:
        # 记录错误日志
        error_log = f"{datetime.now().strftime('%d/%m/%Y %H:%M:%S')} 复制失败:{str(e)}\n"
        with open(log_path, "a") as log_file:
            log_file.write(error_log)
        print(error_log)

# 执行复制
recursive_copy_with_ignore()

方式二:详细日志记录(进阶版)

如果你需要记录每个被复制的文件,可以自定义ignore函数,同时完成过滤和日志记录:

import os
import shutil
from datetime import datetime

src = "E:\\Test\\src"
dest = "E:\\Test\\dest"
log_path = "E:\\Test\\upgrade.log"

def log_and_filter_files(src_dir, file_names):
    """自定义ignore函数:过滤指定文件并记录复制日志"""
    files_to_ignore = set()
    with open(log_path, "a") as log_file:
        for name in file_names:
            full_src_path = os.path.join(src_dir, name)
            # 只处理文件(跳过目录,copytree会自动处理目录)
            if os.path.isfile(full_src_path):
                if name.endswith((".py", ".log")):
                    # 标记要忽略的文件
                    files_to_ignore.add(name)
                else:
                    # 计算目标路径(保留原目录结构)
                    relative_path = os.path.relpath(full_src_path, src)
                    full_dest_path = os.path.join(dest, relative_path)
                    # 记录复制日志
                    log_entry = f"{datetime.now().strftime('%d/%m/%Y %H:%M:%S')} 复制文件:{full_src_path} → {full_dest_path}\n"
                    log_file.write(log_entry)
                    print(log_entry)
    return files_to_ignore

try:
    shutil.copytree(src, dest, ignore=log_and_filter_files, dirs_exist_ok=True)
    final_log = f"{datetime.now().strftime('%d/%m/%Y %H:%M:%S')} 所有文件复制完成\n"
    with open(log_path, "a") as log_file:
        log_file.write(final_log)
    print(final_log)
except Exception as e:
    error_log = f"{datetime.now().strftime('%d/%m/%Y %H:%M:%S')} 复制失败:{str(e)}\n"
    with open(log_path, "a") as log_file:
        log_file.write(error_log)
    print(error_log)

关键说明

  • shutil.copytree是Python官方推荐的递归目录复制工具,完全避免了手动遍历目录的繁琐和错误
  • ignore_patterns可以直接传入通配符模式,快速过滤不需要的文件
  • dirs_exist_ok=True参数解决了目标目录已存在的报错问题,如果你使用Python3.8以下版本,可以先通过os.makedirs(dest, exist_ok=True)提前创建目标目录再复制

内容的提问来源于stack exchange,提问作者whoami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:32:51