Python tempfile模块核心价值在于自动管理生命周期、避免命名冲突、适配平台路径、防止敏感数据残留;手动拼接/tmp路径会因跨平台差异、并发冲突、崩溃残留、权限问题引发错误。
临时文件不是“随便建个 /tmp/file 就完事”,Python 的 tempfile 模块核心价值在于:自动管理生命周期、避免命名冲突、适配不同平台路径规则,以及关键——防止敏感数据残留。
open('/tmp/xxx', 'w')
手动拼接路径会踩一堆坑:/tmp 在 Windows 上不存在;并发时文件名可能重复导致覆盖或 PermissionError;程序崩溃后文件不会自动清理;临时目录权限可能不满足需求(比如容器里 /tmp 是只读的)。
正确做法是交由 tempfile 模块生成路径:
import tempfile安全创建临时文件对象(自动删除)
with tempfile.NamedTemporaryFile(delete=False, suffix='.log') as f: f.write(b'hello') temp_path = f.name
用完记得手动删(因为 delete=False)
import os os.unlink(temp_path)
delete=False 是必须的,否则文件在 with 块退出时立刻被删,外部进程来不及读取suffix 和 prefix 可控,方便调试识别(如 prefix='myapp_')os.path.abspath() 标准化,无需担心相对路径问题tempfile.mkstemp() 和 NamedTemporaryFile() 怎么选二者都返回文件描述符和路径,但语义与使用场景不同:
tempfile.mkstemp() 返回的是原始 fd,适合需要底层控制(比如传给 os.fork() 后子进程复用)或调用 C 扩展的场景NamedTemporaryFile() 返回的是类文件对象,支持 .write()/.read(),更符合 Python 习惯mkstemp() 创建的文件不会自动关闭,必须显式 os.close(fd),否则可能耗尽 fdimport tempfile import osmkstemp 示例(需手动 close + unlink)
fd, path = tempfile.mkstemp(suffix='.dat', text=False) try: os.write(fd, b'data') finally: os.close(fd) # 必须关 fd os.unlink(path) # 必须删文件
很多场景(如解压 zip、运行测试套件)需要一整个临时目录,tempfile.mkdtemp() 是标准解法:
、唯一、且父目录存在(不像 os.makedirs() 需要自己处理 race condition)0o700(仅属主可读写),某些容器或 CI 环境下其他用户进程无法访问,此时需显式指定 mode=0o755
shutil.rmtree() 清理,别依赖 atexit —— 异常退出时它不一定触发import tempfile import shutiltempdir = tempfile.mkdtemp(prefix='build', mode=0o755) try:
do something...
passfinally: shutil.rmtree(temp_dir) # 必须主动删
临时文件跨进程共享时,Windows 和 Unix 行为差异极大
这是最易翻车的点:Windows 下
NamedTemporaryFile(delete=False)创建的文件,默认无法被其他进程打开(会报PermissionError: [WinError 32]),因为 Python 默认以exclusive模式打开。解决方法只有两个:
tempfile.mktemp()(不推荐,有竞态) + open(..., 'w+b') 手动创建(绕过 Python 的锁机制)tempfile.SpooledTemporaryFile(),它在内存中缓冲,超过阈值才落盘,且无文件锁限制(但不适用于大文件或需要磁盘路径的场景)如果你的代码要跑在 Windows CI 上且涉及多进程读写临时文件,优先考虑把临时文件逻辑抽成独立服务,或改用消息队列/数据库代替文件共享。