Python脚本为何移动所有文件而非仅最新文件?代码错误排查
问题说明
编写的Python脚本预期实现两个功能:
- 筛选源路径下最后修改时间不足1天的文件,跨磁盘移动到目标路径
- 生成带日期戳的文件移动操作日志
实际运行时脚本会移动源目录下的所有文件,完全没有按修改时间规则做筛选。
原问题代码
import os import datetime import shutil source = 'C:/Users/user/Desktop/Files to move/' destination = 'C:/Users/user/Desktop/Delete Logs/' today = datetime.datetime.today() # Get current time # Create log file with datestamp file=open(logging_path+datetime.datetime.today().strftime('%d-%m-%Y')+'.txt', 'a') # Move files allfiles = os.listdir(source) for f in allfiles: # Check last modified time t = os.stat(os.path.join(f, source))[8] filetime = datetime.datetime.fromtimestamp(t) - today # Is file less than a day old? If yes, move. if filetime.days <= 1: print(os.path.join(f, source), filetime.days) file.write(os.path.join(f, source) + ' created ' + str(-1 * filetime.days)+' day(s) ago has moved\n') shutil.move(source + f, destination + f)
核心错误说明
一共5个直接导致功能异常的问题:
- 未定义日志路径变量:代码里用到的
logging_path没有提前赋值,运行到打开日志文件的行就会抛出NameError,正常情况下根本无法执行到后续文件移动逻辑。 - 路径拼接顺序完全错误,触发了
os.path.join的绝对路径覆盖特性:代码写的os.path.join(f, source)把文件名放在第一个参数、源目录绝对路径放在第二个参数,os.path.join遇到绝对路径参数时会直接丢弃前面拼接的所有内容,所以不管f是什么文件名,这个拼接结果永远是源目录本身的路径,相当于每次循环都在读取源文件夹的元数据,根本没有读取单个文件的修改时间,这是筛选规则完全失效的最核心原因。 - 时间差计算逻辑倒置:代码用「文件修改时间 - 当前时间」计算差值,对于所有已经存在的历史文件,这个差值永远是负数,负数的
days属性必然小于等于1,判断条件永远成立。 - 用魔数索引读取stat属性可靠性极差:代码用下标
[8]取时间值,不同操作系统下stat返回结果的索引对应属性不完全一致,Windows、macOS、Linux下相同索引可能对应访问时间、修改时间、创建时间不同属性,非常容易取错值。 - 判断阈值不符合需求:就算路径和时间差逻辑正确,
filetime.days <= 1的条件会把修改时间在24-48小时区间的文件也判定为符合要求,和「不足1天」的需求不匹配。 - 日志和打印的路径拼接错误:同样因为
os.path.join(f, source)的写法错误,日志里记录的根本不是真实移动的文件路径。
修复后可正常运行的代码
import os import datetime import shutil source = 'C:/Users/user/Desktop/Files to move/' destination = 'C:/Users/user/Desktop/Delete Logs/' # 明确定义日志存放路径,示例配置为和目标路径同目录,可自行修改 logging_path = destination # 提前判断目标目录、日志目录是否存在,不存在则自动创建 os.makedirs(destination, exist_ok=True) os.makedirs(logging_path, exist_ok=True) today = datetime.datetime.today() log_file_path = os.path.join(logging_path, today.strftime('%d-%m-%Y') + '.txt') # 用上下文管理器打开日志,自动处理文件关闭,指定编码避免中文乱码 with open(log_file_path, 'a', encoding='utf-8') as log_file: allfiles = os.listdir(source) for f in allfiles: source_file_path = os.path.join(source, f) # 跳过子目录,仅处理文件 if not os.path.isfile(source_file_path): continue # 直接用命名属性取文件修改时间,避免魔数索引的跨平台问题 file_mtime = os.stat(source_file_path).st_mtime file_modify_time = datetime.datetime.fromtimestamp(file_mtime) # 正确计算时间差:当前时间 - 文件修改时间 time_diff = today - file_modify_time # 判断文件修改时间距现在是否不足1天 if time_diff.days < 1: dest_file_path = os.path.join(destination, f) print(f"移动文件:{source_file_path},距上次修改{time_diff}") log_file.write(f"{source_file_path} 距上次修改不足1天,已移动到{dest_file_path}\n") shutil.move(source_file_path, dest_file_path)
内容的提问来源于stack exchange,提问作者AmazinAzn
相关产品推荐
相关产品推荐

