登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  python教程

Python 临时文件怎么创建并自动清理

来源:17golang原创

时间:2026-09-06 10:30:41 345浏览 收藏

处理上传文件、压缩中间结果或导出预览时,临时文件最好交给 tempfile 管理。只在当前代码块内使用内容,就选 TemporaryFile;需要把路径交给另一个程序,就选 NamedTemporaryFile;一次任务产生一组文件,则用 TemporaryDirectory。它们都能和 with 一起使用,异常退出也会走清理逻辑。

要点速览
  • 临时文件不需要路径时,TemporaryFile 是最省心的默认选择。
  • 需要可见文件名时使用 NamedTemporaryFile,Windows 下重开文件要特别处理 delete_on_close
  • 多个中间产物放进 TemporaryDirectory,离开上下文后目录和内容一起回收。
  • mkstemp()mkdtemp() 是底层接口,必须自己关闭句柄并删除路径。

先按“是否需要路径”选择临时文件接口

这个选择比记住一堆参数更重要。TemporaryFile 返回类文件对象,适合写入后立即读取;NamedTemporaryFile 保证有可见的 nameTemporaryDirectory 管理的是目录树。下面这张关系图把数据生命周期和清理责任放在一起看。

Python tempfile 三种高层接口分别对应无路径文件、可见文件名和目录树清理
图1:根据是否需要可见路径选择 tempfile 接口,并沿着上下文边界确认文件或目录的清理责任。
需求接口清理方式
当前函数内读写TemporaryFile关闭或离开 with 自动删除
把路径交给外部工具NamedTemporaryFiledeletedelete_on_close 决定
多个中间文件TemporaryDirectory上下文结束时删除目录树

只在当前流程读写时用 TemporaryFile

例如把一段 JSON 先写入临时对象,再交给解析器读取。默认模式是二进制,文本场景可以明确传入 mode="w+"encoding。游标写完要回到开头,否则读到的会是空内容。

import json
import tempfile

def load_preview(payload: dict) -> dict:
    # with 结束时关闭并清理临时文件
    with tempfile.TemporaryFile(mode="w+", encoding="utf-8") as temp:
        json.dump(payload, temp, ensure_ascii=False)
        # 写入后把游标移回文件开头
        temp.seek(0)
        return json.load(temp)

这里不需要知道真实路径,也不需要在 finally 中手动删除。函数返回前离开 with,文件对象会关闭,临时内容随之回收。若逻辑必须让另一个进程按路径打开,就不要硬套这个接口。

需要文件名时处理 NamedTemporaryFile 的关闭边界

文件上传或调用外部命令时,常常需要把路径放进参数。此时可以先创建命名临时文件,再关闭它,让外部程序重新打开。Python 文档特别建议在上下文中使用 delete_on_close=False:关闭文件后仍保留路径,退出 with 时再自动清理。

from pathlib import Path
import tempfile

def handoff_to_tool(data: bytes) -> str:
    # 退出 with 后仍会删除文件,避免遗留中间产物
    with tempfile.NamedTemporaryFile(
        mode="wb", suffix=".bin", delete_on_close=False
    ) as temp:
        temp.write(data)
        temp.flush()
        path = Path(temp.name)
        # 外部工具应在这里按 path 读取,且先确保句柄已关闭
        temp.close()
        consume_path(path)
        return str(path)

def consume_path(path: Path) -> None:
    # 示例边界:真实项目可在此调用受控的外部工具
    if not path.is_file():
        raise FileNotFoundError(path)
Python NamedTemporaryFile 展示可见路径、关闭后重开和上下文退出清理的关系
图2:命名临时文件的关键不只是拿到 name,还要让重开动作发生在合适的关闭边界内,最终仍由上下文负责回收。

在 POSIX 系统中,打开中的命名临时文件通常可以再次打开;Windows 对删除共享更严格。为了跨平台,外部程序读取前先关闭临时文件通常更稳。若把 delete=False,清理责任就转移给你的代码,不能因为测试通过就把删除遗漏到生产环境。

多个中间产物用 TemporaryDirectory 集中清理

压缩、转换或批量导出往往不止一个文件。用独立目录包住这一组中间结果,成功、异常和提前返回都会经过同一个生命周期出口:

from pathlib import Path
import tempfile

def build_bundle(source: bytes) -> bytes:
    with tempfile.TemporaryDirectory(prefix="bundle-") as temp_dir:
        root = Path(temp_dir)
        raw = root / "source.bin"
        result = root / "result.bin"
        # 中间文件都限制在本次任务的临时目录中
        raw.write_bytes(source)
        transform(raw, result)
        return result.read_bytes()

def transform(source: Path, target: Path) -> None:
    # 示例转换:真实项目在这里写入转换后的结果
    target.write_bytes(source.read_bytes())

不要在 with 外继续使用 root 下的路径:目录已经被清理。确实需要保留结果时,应在退出前复制到明确的持久目录,并把“临时”和“最终产物”区分开。

底层 mkstemp 什么时候需要自己清理

mkstemp() 返回文件描述符和绝对路径,适合需要操作系统级句柄的场景,但它不会替你关闭和删除。手动代码至少要同时覆盖句柄释放与路径删除,且删除动作放在 finally

import os
import tempfile

def write_low_level(data: bytes) -> str:
    fd, path = tempfile.mkstemp(suffix=".bin")
    try:
        # fd 是已打开的底层句柄,写完要显式关闭
        with os.fdopen(fd, "wb") as temp:
            temp.write(data)
        return path
    finally:
        # 无论写入或后续处理是否抛错,都清理临时路径
        if os.path.exists(path):
            os.remove(path)

上例只演示责任边界:如果返回路径给调用方继续使用,就不能在函数的 finally 中删除,而要把删除责任交给更外层的拥有者。不要使用已经弃用的 mktemp(),它先返回名字、后创建文件,中间存在竞态窗口。

常见问题

临时文件默认会放在哪里?

TMPDIRTEMPTMP 等环境变量和平台默认目录共同决定。需要固定位置时给接口传 dir,不要修改模块级的 tempdir

为什么写完临时文件后读取不到内容?

文件游标仍停在末尾。写入后调用 seek(0),或者关闭文件后再按路径读取。

delete 和 delete_on_close 有什么区别?

delete 决定是否启用自动删除;delete_on_close 决定删除更偏向关闭时发生,还是延迟到上下文退出。需要关闭后重开时,优先在 with 中使用 delete_on_close=False

把临时文件当成有明确拥有者的资源:创建者决定接口,使用者决定关闭边界,生命周期结束处负责清理。这样即使处理逻辑抛出异常,也不会把“临时”变成服务器上的长期垃圾。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>