shutil.copy2在循环中仅复制单个文件后停止,该如何修复
问题根因
两个函数的核心错误都是**shutil.copy2的缩进位置错误**:
当前代码里复制操作被缩进到了「判断目录不存在」的if分支内部,只有第一次创建目标目录的时候才会执行复制,后续目录已经存在,就不会进入if分支,自然不会触发复制操作,所以只会复制第一个需要创建目录的文件。
修复方案
首先调整缩进把复制操作移到目录判断的同级,其次可以优化Excel读取逻辑,提前把所有商品编号读入集合,减少重复遍历提升效率,修复后代码如下:
import os import openpyxl import shutil def copy_images(excel_path): src = r'D:\src_img' destination_folder = r'D:\dest_img' # 提前读取所有商品编号到集合,避免每次遍历文件都循环Excel行 wb = openpyxl.load_workbook(excel_path) sheet = wb.active # 过滤空单元格,避免None转为字符串'None'出现误匹配 product_numbers = {str(sheet.cell(row, 1).value).strip() for row in range(2, sheet.max_row + 1) if sheet.cell(row, 1).value is not None} for path, subdirs, files in os.walk(src): for name in files: filename = os.path.join(path, name) # 直接匹配集合内的编号,无需重复遍历Excel行 for pn in product_numbers: if pn in filename: full_dest_path = os.path.join(destination_folder, filename.lstrip(src).lstrip('/\\')) dirname = os.path.dirname(full_dest_path) if not os.path.exists(dirname): os.makedirs(dirname) # 缩进调整:复制操作移到if判断外部,不管目录是否新建都执行复制 shutil.copy2(filename, full_dest_path) # 匹配到对应编号后直接跳出循环,避免同一个文件匹配多个编号重复复制 break def update_images(excel_path): src = r'D:\src_img' dest = r'D:\dest_img' # 提前读取所有商品编号到集合 wb = openpyxl.load_workbook(excel_path) sheet = wb.active product_numbers = {str(sheet.cell(row, 1).value).strip() for row in range(2, sheet.max_row + 1) if sheet.cell(row, 1).value is not None} # 提前创建目标根目录,无需每次匹配到文件都重复判断 if not os.path.exists(dest): os.makedirs(dest) for path, subdirs, files in os.walk(src): for name in files: filename = os.path.join(path, name) for pn in product_numbers: if pn in filename: # 缩进调整:复制操作和目录判断平级 shutil.copy2(filename, os.path.join(dest, name)) break
额外优化说明
- 提前读取商品编号到集合,原代码每次遍历一个文件就要循环一遍所有Excel行,文件数量多的时候效率极低,优化后运行速度提升明显
- 增加空值过滤,避免Excel空单元格转为
'None'字符串后误匹配文件名 - 匹配到对应编号后直接跳出循环,避免同一个文件匹配多个编号重复复制
update_images里把目标根目录的判断提到循环外,不用每次匹配到文件都重复判断目录是否存在
内容的提问来源于stack exchange,提问作者bardukiss
相关产品推荐
相关产品推荐

