# `tempfile` --- 生成临时文件和目录

源代码： Lib/tempfile.py

该模块可以创建临时文件和目录。 它适用于所有受支持的平台。 `TemporaryFile`, `NamedTemporaryFile`, `TemporaryDirectory` 和 `SpooledTemporaryFile` 是提供自动清理功能的高层级接口并可用作 上下文管理器。 `mkstemp()` 和 `mkdtemp()` 是需要执行手动清理的低层级函数。

所有由用户调用的函数和构造函数都带有参数，这些参数可以设置临时文件和临时目录的路径和名称。该模块生成的文件名包括一串随机字符，在公共的临时目录中，这些字符可以让创建文件更加安全。为了保持向后兼容性，参数的顺序有些奇怪。所以为了代码清晰，建议使用关键字参数。

这个模块定义了以下内容供用户调用：

tempfile.TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

  返回一个 file-like object 作为临时存储区域。创建该文件使用了与 `mkstemp()` 相同的安全规则。它将在关闭后立即销毁（包括垃圾回收机制关闭该对象时）。在 Unix 下，该文件在目录中的条目根本不创建，或者创建文件后立即就被删除了，其他平台不支持此功能。您的代码不应依赖使用此功能创建的临时文件名称，因为它在文件系统中的名称可能是可见的，也可能是不可见的。

  结果对象可以用作 context manager (参见 例子)。 上下文结束或文件对象销毁后会将临时文件从文件系统中移除。

  mode 参数默认值为 `'w+b'`，所以创建的文件不用关闭，就可以读取或写入。因为用的是二进制模式，所以无论存的是什么数据，它在所有平台上都表现一致。buffering、encoding、errors 和 newline 的含义与 `open()` 中的相同。

  参数 dir、prefix 和 suffix 的含义和默认值都与它们在 `mkstemp()` 中的相同。

  在 POSIX 平台上，它返回的对象是真实的文件对象。在其他平台上，它是一个文件型对象，它的 `file` 属性是底层的真实文件对象。

  在可用且有效时将使用 `os.O_TMPFILE` 旗标（Linux 专属，需要 Linux 内核版本为 3.11 或更高）。

  在 Posix 或 Cygwin 以外的平台上，TemporaryFile 是 NamedTemporaryFile 的别名。

  引发一个 审计事件 `tempfile.mkstemp` 并附带参数 `fullpath`。

  在 3.5 版本发生变更: 在可以时现在将使用 `os.O_TMPFILE` 旗标。

  在 3.8 版本发生变更: 添加了 errors 参数。

tempfile.NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None)

  此函数执行的操作与 `TemporaryFile()` 完全相同，但是会确保该文件在文件系统中具有可见的名称（在 Unix 上表现为目录项不取消链接）。 该名称可从返回的文件类对象的 `name` 属性获取。 在指定的临时文件仍然被打开时该名称是否可被用来再次打开文件对于不同平台则有所不同（在 Unix 上可以这样做；在 Windows 上不可以） 如果 delete 为（默认的）真值，则文件会在关闭之后立即被删除。 此函数返回的对象始终会是文件类对象，它的 `file` 属性是底层的真实文件对象。 这个文件类对象可以在 `with` 语句中使用，就像普通的文件一样。

  （只有）在 POSIX 上，一个用 SIGKILL 突然终止的进程无法自动删除它所创建的任何 NamedTemporaryFiles。

  引发一个 审计事件 `tempfile.mkstemp` 并附带参数 `fullpath`。

  在 3.8 版本发生变更: 添加了 errors 参数。

class tempfile.SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

  这个类执行的操作与 `TemporaryFile()` 完全相同，但会将数据放入内存池直到文件大小超过 max_size，或者直到文件的 `fileno()` 方法被调用，这时文件内容会被写入磁盘并如使用 `TemporaryFile()` 时一样执行后续操作。

  rollover()

    结果文件有一个额外的方法 `rollover()`，它可以忽略文件大小将其立即写入到磁盘文件。

  返回的对象是一个文件型对象，它的 `_file` 属性是 `io.BytesIO` 或 `io.TextIOWrapper` 对象（这取决于所指定的 mode 是二进制还是文本）或真实的文件对象，这取决于 `rollover()` 是否已被调用。 这个文件型对象可以像普通文件一样在 `with` 语句中使用。

  在 3.3 版本发生变更: 现在 truncate 方法可接受一个 size 参数。

  在 3.8 版本发生变更: 添加了 errors 参数。

  在 3.11 版本发生变更: 完整实现 `io.BufferedIOBase` 和 `io.TextIOBase` 抽象基类（取决于二进制或文本 mode 是否已指定）。

class tempfile.TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False)

  这个类会使用与 `mkdtemp()` 相同的规则安全地创建一个临时目录。 结果对象可以被用作 context manager (参见 例子)。 在完成上下文或销毁临时目录对象时，新创建的临时目录及其所有内容会从文件系统中被移除。

  name

    可以从所返回对象的 `name` 属性中提取目录名称。 当返回的对象被用作 context manager 时，这个 `name` 将被作为 `with` 语句中 `as` 子句的目标，如果存在该子句的话。

  cleanup()

    此目录可通过调用 `cleanup()` 方法来显式地清理。 如果 ignore_cleanup_errors 为真值，则在显式或隐式清理（例如在 Windows 上 `PermissionError` 移除打开的文件）期间出现的未处理异常将被忽略，并且剩余的可移除条目会被“尽可能”地删除。 在其他情况下，错误将在任何上下文清理发生时被引发（如 `cleanup()` 调用，退出上下文管理器、对象被作为垃圾回收或解释器关闭等情况）。

  引发一个 审计事件 `tempfile.mkdtemp` 并附带参数 `fullpath`。

  在 3.2 版本加入.

  在 3.10 版本发生变更: 添加了 ignore_cleanup_errors 形参。

tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)

  以最安全的方式创建一个临时文件。假设所在平台正确实现了 `os.open()` 的 `os.O_EXCL` 标志，则创建文件时不会有竞争的情况。该文件只能由创建者读写，如果所在平台用权限位来标记文件是否可执行，那么没有人有执行权。文件描述符不会过继给子进程。

  与 `TemporaryFile()` 不同，`mkstemp()` 用户用完临时文件后需要自行将其删除。

  如果 suffix 不是 `None` 则文件名将以该后缀结尾，是 `None` 则没有后缀。`mkstemp()` 不会在文件名和后缀之间加点，如果需要加一个点号，请将其放在 suffix 的开头。

  如果 prefix 不是 `None`，则文件名将以该前缀开头，是 `None` 则使用默认前缀。默认前缀是 `gettempprefix()` 或 `gettempprefixb()` 函数的返回值（自动调用合适的函数）。

  如果 dir 不为 `None`，则在指定的目录创建文件，是 `None` 则使用默认目录。默认目录是从一个列表中选择出来的，这个列表不同平台不一样，但是用户可以设置 TMPDIR、TEMP 或 TMP 环境变量来设置目录的位置。因此，不能保证生成的临时文件路径很规范，比如，通过 `os.popen()` 将路径传递给外部命令时仍需要加引号。

  如果 suffix、prefix 和 dir 中的任何一个不是 `None`，就要保证它们是同一数据类型。如果它们是 bytes，则返回的名称的类型就是 bytes 而不是 str。如果确实要用默认参数，但又想要返回值是 bytes 类型，请传入 `suffix=b''`。

  如果指定了 text 且为真值，文件会以文本模式打开。 否则，文件（默认）会以二进制模式打开。

  `mkstemp()` 返回一个元组，元组中第一个元素是句柄，它是一个系统级句柄，指向一个打开的文件（等同于 `os.open()` 的返回值），第二元素是该文件的绝对路径。

  引发一个 审计事件 `tempfile.mkstemp` 并附带参数 `fullpath`。

  在 3.5 版本发生变更: 现在，suffix、prefix 和 dir 可以以 bytes 类型按顺序提供，以获得 bytes 类型的返回值。之前只允许使用 str。suffix 和 prefix 现在可以接受 `None`，并且默认为 `None` 以使用合适的默认值。

  在 3.6 版本发生变更: dir 参数现在可接受一个路径类对象 (path-like object)。

tempfile.mkdtemp(suffix=None, prefix=None, dir=None)

  以最安全的方式创建一个临时目录，创建该目录时不会有竞争的情况。该目录只能由创建者读取、写入和搜索。

  `mkdtemp()` 用户用完临时目录后需要自行将其删除。

  prefix、suffix 和 dir 的含义与它们在 `mkstemp()` 中的相同。

  `mkdtemp()` returns the absolute pathname of the new directory if dir is `None` or is an absolute path. If dir is a relative path, `mkdtemp()` returns a relative path on Python 3.11 and lower. However, on 3.12 it will return an absolute path in all situations.

  引发一个 审计事件 `tempfile.mkdtemp` 并附带参数 `fullpath`。

  在 3.5 版本发生变更: 现在，suffix、prefix 和 dir 可以以 bytes 类型按顺序提供，以获得 bytes 类型的返回值。之前只允许使用 str。suffix 和 prefix 现在可以接受 `None`，并且默认为 `None` 以使用合适的默认值。

  在 3.6 版本发生变更: dir 参数现在可接受一个路径类对象 (path-like object)。

tempfile.gettempdir()

  返回放置临时文件的目录的名称。这个方法的返回值就是本模块所有函数的 dir 参数的默认值。

  Python 搜索标准目录列表，以找到调用者可以在其中创建文件的目录。这个列表是：

  1. `TMPDIR` 环境变量指向的目录。

  2. `TEMP` 环境变量指向的目录。

  3. `TMP` 环境变量指向的目录。

  4. 与平台相关的位置：

     - 在 Windows 上，依次为 `C:\TEMP`、`C:\TMP`、`\TEMP` 和 `\TMP`。

     - 在所有其他平台上，依次为 `/tmp`、`/var/tmp` 和 `/usr/tmp`。

  5. 不得已时，使用当前工作目录。

  搜索的结果会缓存起来，参见下面 `tempdir` 的描述。

  在 3.10 版本发生变更: 总是返回一个字符串。 在之前的版本中它会返回任意 `tempdir` 值而不考虑它的类型，只要它不为 `None`。

tempfile.gettempdirb()

  与 `gettempdir()` 相同，但返回值为字节类型。

  在 3.5 版本加入.

tempfile.gettempprefix()

  返回用于创建临时文件的文件名前缀，它不包含目录部分。

tempfile.gettempprefixb()

  与 `gettempprefix()` 相同，但返回值为字节类型。

  在 3.5 版本加入.

本模块使用一个全局变量来存储由 `gettempdir()` 返回的临时文件使用的目录路径。 它可被直接设置以覆盖选择过程，但不建议这样做。 本模块中的所有函数都接受一个 dir 参数，它可被用于指定目录。 这是不会通过改变全局 API 行为对其他无准备代码造成影响的推荐做法。

tempfile.tempdir

  当设为 `None` 以外的值时，此变量会为本模块中定义的函数的 dir 参数定义默认值，包括确定其类型为字节串还是字符串。 它不可以为 path-like object。

  如果在调用除 `gettempprefix()` 外的上述任何函数时 `tempdir` 为 `None` (默认值) 则它会按照 `gettempdir()` 中所描述的算法来初始化。

  备注

  请注意如果你将 `tempdir` 设为字节串值，会有一个麻烦的副作用: `mkstemp()` 和 `mkdtemp()` 的全局默认返回类型会在没有显式提供字符串类型的when no explicit `prefix`, `suffix` 或 `dir` 的时候被改为字节串。 请不要编写预期或依赖于此入围的代码。 这个笨拙行为是为了保持与历史实现的兼容性。

## 例子

以下是 `tempfile` 模块典型用法的一些示例:

    >>> import tempfile

    # create a temporary file and write some data to it
    >>> fp = tempfile.TemporaryFile()
    >>> fp.write(b'Hello world!')
    # read data from file
    >>> fp.seek(0)
    >>> fp.read()
    b'Hello world!'
    # close the file, it will be removed
    >>> fp.close()

    # create a temporary file using a context manager
    >>> with tempfile.TemporaryFile() as fp:
    ...     fp.write(b'Hello world!')
    ...     fp.seek(0)
    ...     fp.read()
    b'Hello world!'
    >>>
    # file is now closed and removed

    # create a temporary directory using the context manager
    >>> with tempfile.TemporaryDirectory() as tmpdirname:
    ...     print('created temporary directory', tmpdirname)
    >>>
    # directory and contents have been removed

## 已弃用的函数和变量

创建临时文件有一种历史方法，首先使用 `mktemp()` 函数生成一个文件名，然后使用该文件名创建文件。不幸的是，这是不安全的，因为在调用 `mktemp()` 与随后尝试创建文件的进程之间的时间里，其他进程可能会使用该名称创建文件。解决方案是将两个步骤结合起来，立即创建文件。这个方案目前被 `mkstemp()` 和上述其他函数所采用。

tempfile.mktemp(suffix='', prefix='tmp', dir=None)

  自 2.3 版本弃用: 使用 `mkstemp()` 来代替。

  返回一个绝对路径，这个路径指向的文件在调用本方法时不存在。prefix、suffix 和 dir 参数与 `mkstemp()` 中的同名参数类似，不同之处在于不支持字节类型的文件名，不支持 `suffix=None` 和 `prefix=None`。

  警告

  使用此功能可能会在程序中引入安全漏洞。当你开始使用本方法返回的文件执行任何操作时，可能有人已经捷足先登了。`mktemp()` 的功能可以很轻松地用 `NamedTemporaryFile()` 代替，当然需要传递 `delete=False` 参数:

      >>> f = NamedTemporaryFile(delete=False)
      >>> f.name
      '/tmp/tmptjujjt'
      >>> f.write(b"Hello World!\n")
      13
      >>> f.close()
      >>> os.unlink(f.name)
      >>> os.path.exists(f.name)
      False