os.path.getmtime返回Unix时间戳,需转datetime或直接用时间差判断过期;os.remove应捕获FileNotFoundError和PermissionError;目录遍历优先用os.walk();路径拼接用os.path.join();大目录优化用os.stat()或pathlib.Path.stat()。

os.path.getmtime 返回的是时间戳,不是可读日期
很多人直接拿 os.path.getmtime 的返回值和字符串日期(比如 "2024-01-01")比,结果永远不匹配。它返回的是秒级浮点数,从 Unix 纪元开始算的,得转成 datetime 或用 time.time() 做减法。
- 判断“过期”最稳妥的方式是:当前时间戳 - 文件修改时间戳 > 过期秒数
- 别用
datetime.fromtimestamp()再格式化成字符串去比对,多此一举还容易因时区出错 - 如果必须用日期对象比较,统一用
datetime.utcfromtimestamp()避免本地时区干扰
os.remove 会报 FileNotFoundError,但文件可能已被其他进程删了
并发清理或脚本被多次触发时,os.remove 很容易遇到 FileNotFoundError。这不是代码写错了,而是典型的竞态条件 —— 你查完文件存在,还没来得及删,另一个进程先下手了。
- 推荐用
try/except捕获FileNotFoundError和PermissionError,而不是提前os.path.exists判断(后者反而增加竞态窗口) - 不要忽略
PermissionError,尤其在 Windows 上,只读文件或正在被打开的 log 文件常触发这个 - 示例写法:
try: os.remove(filepath) except (FileNotFoundError, PermissionError): pass # 安静跳过,不打断整个流程
递归遍历目录时,os.walk() 比 glob + os.listdir 更稳
用 glob.glob("*/log/*.log") 看似简单,但路径通配符不跨层级、不处理符号链接、且在空目录下返回空列表难以调试;而 os.walk() 天然支持深度优先遍历,还能控制是否进入子目录。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 注意
os.walk()默认会遍历所有子目录,如果只想清理某一层(比如只清logs/下的,不进logs/archive/),得手动跳过:if "archive" in dirs: dirs.remove("archive") - 路径拼接务必用
os.path.join(root, file),别用字符串拼接,Windows 下反斜杠会出问题 - 避免在遍历中直接
os.remove同一目录下的文件,虽然一般不影响,但某些文件系统(如 NFS)可能引发OSError: [Errno 13] Permission denied
大目录下反复调用 os.path.getmtime 影响性能
一个含 10 万文件的目录,逐个调用 os.path.getmtime 可能卡住几秒 —— 不是 Python 慢,是每次都要走一次系统调用,内核要查 inode。
- 如果只需要删“30 天前”的文件,可以先用
os.stat()一次性拿到st_mtime和st_size等多个字段,省一次系统调用 - 更激进的优化:用
pathlib.Path.stat()替代os.path.getmtime,底层一样,但 API 更干净,且Path对象可缓存 - 真正海量文件(百万级),建议改用 shell 命令外包,比如 Linux 下
find /path -name "*.log" -mtime +30 -delete,由 C 实现的find效率高得多
实际清理逻辑里最容易被绕开的,是“修改时间 vs 创建时间 vs 访问时间”的混淆 —— os.path.getmtime 是修改时间,但很多日志轮转工具(如 logrotate)改名后文件 mtime 不变,这时候删出来的根本不是你想要的“老文件”。真要按生成逻辑判断,得结合文件名里的日期字段,而不是无脑信 mtime。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










