多文件夹最新文件迁移报错排查及key参数咨询
解决文件迁移报错问题并解释
key=os.path.getctime的作用 首先来分析你遇到的NotADirectoryError:
你的代码里filePath是单个文件的完整路径(比如c:\data\AS\Desktop\Source\A\12.txt),但os.listdir()要求传入的是目录路径,不是文件路径,所以才会抛出这个错误。你的核心逻辑是要找每个子文件夹(A/B/C)里的最新文件,不需要嵌套两层os.walk,我们可以简化逻辑并修正错误。
修正后的代码
我重新写了代码,同时做了这些优化:
- 自动检查并创建Destination和Archive下的A/B/C子目录,避免移动时找不到目录
- 直接遍历Source下的一级子目录,精准定位A/B/C
- 正确获取每个子目录下的所有文件,找出最新的那个
- 分别将最新文件移动到Destination对应目录,其余文件移动到Archive对应目录
from datetime import datetime import shutil, os # 定义路径 source = r'c:\data\AS\Desktop\Source' destination = r'c:\data\AS\Desktop\Destination' archive = r'c:\data\AS\Desktop\Archive' # 遍历Source下的一级子目录(A、B、C) for folder_name in os.listdir(source): source_folder = os.path.join(source, folder_name) # 确保当前路径是目录(避免Source下直接有文件的情况) if not os.path.isdir(source_folder): continue # 创建对应的Destination和Archive子目录(不存在则创建) dest_folder = os.path.join(destination, folder_name) arch_folder = os.path.join(archive, folder_name) os.makedirs(dest_folder, exist_ok=True) os.makedirs(arch_folder, exist_ok=True) # 获取当前子目录下的所有文件(排除子目录) files = [f for f in os.listdir(source_folder) if os.path.isfile(os.path.join(source_folder, f))] if not files: print(f"子目录 {folder_name} 中没有文件,跳过") continue # 找出最新的文件:根据创建时间(ctime)排序 # 这里用os.path.getctime获取文件的创建时间戳 latest_file = max(files, key=lambda f: os.path.getctime(os.path.join(source_folder, f))) # 遍历所有文件,分别迁移 for file in files: source_file_path = os.path.join(source_folder, file) if file == latest_file: # 最新文件移到Destination shutil.move(source_file_path, os.path.join(dest_folder, file)) print(f"已将最新文件 {file} 移动到 {dest_folder}") else: # 非最新文件移到Archive shutil.move(source_file_path, os.path.join(arch_folder, file)) print(f"已将文件 {file} 移动到 {arch_folder}")
关于key=os.path.getctime的解释
在Python的max()函数中,key参数是一个回调函数,作用是指定比较元素大小的依据:
max(iterable, key=函数)会把可迭代对象里的每个元素,传入key指定的函数中- 然后根据函数返回的值来进行大小比较,最终返回对应值最大的那个元素
具体到os.path.getctime(path):
- 在Windows系统中,它返回的是文件的创建时间的时间戳(从1970年1月1日到现在的秒数)
- 在Unix/Linux系统中,它返回的是文件状态最后修改的时间(比如权限变更、所有者变更等)的时间戳
所以max(files, key=lambda f: os.path.getctime(...))的逻辑是:把每个文件名传入lambda函数,获取该文件的ctime时间戳,然后比较这些时间戳,找出时间戳最大(也就是最新)的那个文件名。
内容的提问来源于stack exchange,提问作者ManCity10
相关产品推荐
相关产品推荐

