shutil.move报错:无法将目录移入自身,求Python代码修复方案
问题分析与解决方案
错误原因
你创建的25k-Split_i子目录会被后续的os.listdir(src_dir)读取到,导致代码试图将刚创建的子目录移动到它自己内部,触发报错。比如第一次循环创建25k-Split_0后,os.listdir会把这个新目录包含进去,当它出现在dirs_to_move列表中时,shutil.move就会尝试把它移到自己的子路径下,引发冲突。
修复后的代码
import os import shutil from alive_progress import alive_bar # 源目录 src_dir = r'C:\Users\Administrator\Desktop\base' # 每个子目录包含的目录数量 num_dirs_per_subdir = 25000 # 子目录前缀名称 subdir_base_name = '25k-Split' # 1. 预获取所有需要移动的子目录,排除已存在的拆分目录和文件 original_dirs = [] for item in os.listdir(src_dir): item_path = os.path.join(src_dir, item) # 只保留目录,且过滤掉已生成的拆分目录 if os.path.isdir(item_path) and not item.startswith(subdir_base_name): original_dirs.append(item) # 计算需要创建的子目录总数(向上取整,避免遗漏剩余目录) total_dirs = len(original_dirs) num_subdirs = (total_dirs + num_dirs_per_subdir - 1) // num_dirs_per_subdir # 分批次处理目录移动 for i in range(num_subdirs): # 确定当前批次的目录范围 start_idx = i * num_dirs_per_subdir end_idx = min((i+1)*num_dirs_per_subdir, total_dirs) current_dirs = original_dirs[start_idx:end_idx] # 创建目标子目录(exist_ok=True避免重复创建报错) subdir_path = os.path.join(src_dir, f'{subdir_base_name}_{i}') os.makedirs(subdir_path, exist_ok=True) # 移动目录并显示进度 with alive_bar(len(current_dirs), force_tty=True) as bar: for directory in current_dirs: src_path = os.path.join(src_dir, directory) dst_path = os.path.join(subdir_path, directory) shutil.move(src_path, dst_path) bar()
关键改进点
- 预获取目录列表:一次性拿到所有需要移动的子目录,避免后续创建的拆分目录被误纳入移动列表。
- 过滤无效项:只处理目标子目录,排除已生成的拆分目录和文件,避免无效操作。
- 向上取整计算子目录数:确保总目录数不是25000整数倍时,剩余目录能被分到最后一个子目录。
- 安全创建目录:用
os.makedirs加exist_ok=True,重复运行时不会因目录已存在报错。 - 准确进度显示:进度条总数匹配当前批次的目录数量,进度展示更真实。
内容的提问来源于stack exchange,提问作者KEEP BUSY
相关产品推荐
相关产品推荐

