应禁用tempfile.mktemp(),改用NamedTemporaryFile(delete=False)或mkstemp()配合os.fdopen();临时目录需手动清理,安全性取决于原子创建而非路径随机性。

临时文件被其他进程抢读或覆盖怎么办
直接用 tempfile.mktemp() 生成路径再手动写入,是典型不安全操作——路径生成和文件创建之间存在竞态窗口,恶意程序可能抢先创建同名文件并注入内容。Python 官方早在 3.12 就彻底弃用该函数,报 DeprecationWarning,3.14 起直接抛 RuntimeError。
- 永远改用
tempfile.NamedTemporaryFile()或tempfile.mkstemp(),它们在内核层面原子性地创建并打开文件 - 若需文件名且后续要多次读写,优先选
NamedTemporaryFile(delete=False),关闭后手动管理生命周期 - Linux/macOS 下注意:临时文件默认权限是
0o600(仅属主可读写),Windows 不强制限制,但 Python 会尝试设为0o600;如需跨平台一致行为,显式传mode=0o600
为什么 NamedTemporaryFile 关闭后文件还存在
因为默认参数 delete=True 只在文件对象被垃圾回收时才触发删除,而 Windows 上文件句柄未完全释放前无法删文件——如果忘了调用 .close(),或在异常路径中提前退出,文件就残留了。
- 明确控制生命周期:创建后立刻
.close(),再用os.unlink()删除(仅当delete=False时) - 更稳妥的写法是配合
with语句,但注意:一旦with块结束,文件句柄关闭,Windows 下不能再以相同路径重新打开 - 示例:
with tempfile.NamedTemporaryFile(delete=False) as f: f.write(b"hello") tmp_path = f.name # 此时文件已写完、已关闭,可安全传递给 subprocess 或其他模块 os.unlink(tmp_path) # 手动清理
mkstemp 返回的 fd 怎么转成可读写的 file object
tempfile.mkstemp() 返回的是(文件描述符, 路径)元组,fd 是整数,不能直接调用 .read()。必须用 os.fdopen() 包装,否则容易漏掉缓冲区或权限问题。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 必须指定
mode参数(如"w+b"),否则默认只读,写入会失败 - fd 打开后,原路径只是个字符串,
os.fdopen()创建的对象才真正持有句柄 - 别忘记关闭
fdopen返回的对象,否则 fd 泄漏(尤其在循环中) - 示例:
fd, path = tempfile.mkstemp(suffix=".log") try: with os.fdopen(fd, "w+") as f: f.write("start\n") f.seek(0) print(f.read()) finally: os.unlink(path) # 即使出错也要清理路径
临时目录里文件没自动清理,磁盘快满了
tempfile.gettempdir() 返回的系统临时目录(如 /tmp 或 C:\Users\XXX\AppData\Local\Temp)本身不会自动清理旧文件,Python 的 tempfile 模块也不负责定期扫描。
- 短生命周期脚本:用
tempfile.TemporaryDirectory()上下文管理器,退出时递归删除整个目录 - 长期运行服务:避免把临时文件留在
gettempdir(),改用带时间戳的子目录 + 定期shutil.rmtree()清理 24 小时前的目录 - 注意:
TemporaryDirectory的__exit__方法在异常时仍会尝试删除,但若目录被其他进程占用(如日志正在被 tail),会静默失败——建议捕获OSError并记录
临时文件的安全性不在“名字随机”,而在“创建即独占”。哪怕路径看着像 /tmp/tmpabc123,只要没用原子创建接口,就等于把钥匙挂在门把手上。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










