tempfile — 生成临时文件和目录 — Python 文档

来自菜鸟教程
Python/docs/3.10/library/tempfile
跳转至:导航、​搜索

tempfile — 生成临时文件和目录

源代码: :source:`Lib/tempfile.py`



该模块创建临时文件和目录。 它适用于所有支持的平台。 TemporaryFileNamedTemporaryFileTemporaryDirectorySpooledTemporaryFile 是提供自动清理的高级接口,可用作上下文管理器。 mkstemp()mkdtemp() 是需要手动清理的低级函数。

所有用户可调用的函数和构造函数都采用附加参数,允许直接控制临时文件和目录的位置和名称。 该模块使用的文件名包括一串随机字符,允许在共享临时目录中安全地创建这些文件。 为了保持向后兼容性,参数顺序有点奇怪; 为清楚起见,建议使用关键字参数。

该模块定义了以下用户可调用项:

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

返回一个 类似文件的对象 ,可以用作临时存储区域。 该文件是安全创建的,使用与 mkstemp() 相同的规则。 它会在关闭后立即销毁(包括对象被垃圾回收时的隐式关闭)。 在 Unix 下,文件的目录条目要么根本不创建,要么在文件创建后立即删除。 其他平台不支持; 您的代码不应依赖于使用此函数创建的临时文件,该文件在文件系统中是否具有可见名称。

生成的对象可以用作上下文管理器(参见 示例 )。 完成上下文或文件对象的破坏后,临时文件将从文件系统中删除。

mode参数默认为'w+b',这样创建的文件不关闭就可以读写。 使用二进制模式使其在所有平台上的行为一致,而不考虑存储的数据。 bufferingencodingerrorsnewline 被解释为 open()

dirprefixsuffix 参数具有与 mkstemp() 相同的含义和默认值。

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

如果 os.O_TMPFILE 标志可用且有效(Linux 特定,需要 Linux 内核 3.11 或更高版本),则使用该标志。

3.5 版更改: 现在使用 os.O_TMPFILE 标志(如果可用)。

3.8 版更改: 添加 错误 参数。

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 NT 或更高版本上则不能)。 如果 delete 为真(默认值),文件一关闭就会被删除。 返回的对象始终是一个类文件对象,其 file 属性是底层的真实文件对象。 这个类文件对象可以在 with 语句中使用,就像普通文件一样。

3.8 版更改: 添加 错误 参数。

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(),它会导致文件滚动到磁盘上的文件,而不管其大小。

返回的对象是一个类似文件的对象,其 _file 属性是 io.BytesIOio.TextIOWrapper 对象(取决于是二进制还是文本 mode 已指定)或真实文件对象,具体取决于是否已调用 rollover()。 这个类文件对象可以在 with 语句中使用,就像普通文件一样。

3.3 版更改: truncate 方法现在接受 size 参数。

3.8 版更改: 添加 错误 参数。

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

此函数使用与 mkdtemp() 相同的规则安全地创建一个临时目录。 生成的对象可以用作上下文管理器(参见 示例 )。 在完成上下文或临时目录对象的销毁后,新创建的临时目录及其所有内容将从文件系统中删除。

可以从返回对象的 name 属性中检索目录名称。 当返回的对象用作上下文管理器时,name 将分配给 with 语句中 as 子句的目标,如果有的话。

可以通过调用 cleanup() 方法显式清理目录。 如果 ignore_cleanup_errors 为真,则在显式或隐式清理过程中任何未处理的异常(例如 PermissionError 在 Windows 上删除打开的文件)将被忽略,并在“最佳——努力”的基础。 否则,无论发生什么上下文清理(cleanup() 调用、退出上下文管理器、对象被垃圾收集或解释器关闭期间)都会引发错误。

3.2 版中的新功能。

3.10 版更改: 添加 ignore_cleanup_errors 参数。

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

以最安全的方式创建临时文件。 文件创建中没有竞争条件,假设平台正确实现了 os.open()os.O_EXCL 标志。 该文件只能由创建用户 ID 读取和写入。 如果平台使用权限位来指示文件是否可执行,则该文件不能被任何人执行。 文件描述符不被子进程继承。

TemporaryFile() 不同,mkstemp() 的用户负责在完成后删除临时文件。

如果 suffix 不是 None,则文件名将以该后缀结尾,否则将没有后缀。 mkstemp() 文件名和后缀之间不加点; 如果需要的话,把它放在后缀的开头。

如果 prefix 不是 None,则文件名将以该前缀开头; 否则,将使用默认前缀。 默认为 gettempprefix()gettempprefixb() 的返回值,视情况而定。

如果 dir 不是 None,则会在该目录中创建文件; 否则,将使用默认目录。 默认目录是从依赖于平台的列表中选择的,但应用程序的用户可以通过设置 TMPDIRTEMPTMP 环境来控制目录位置变量。 因此,不能保证生成的文件名具有任何好的属性,例如在通过 os.popen() 传递给外部命令时不需要引用。

如果suffixprefixdir中的任何一个不是None,它们必须是相同的类型。 如果它们是字节,则返回的名称将是字节而不是 str。 如果要强制使用默认行为的字节返回值,请传递 suffix=b

如果指定了 text 并且为真,则文件以文本模式打开。 否则,(默认)文件以二进制模式打开。

mkstemp() 返回一个包含操作系统级句柄的元组到一个打开的文件(由 os.open() 返回)和该文件的绝对路径名,在那个命令。

在 3.5 版中更改:suffixprefixdir 现在可以以字节为单位提供,以获得字节返回值。 在此之前,只允许 str 。 suffixprefix 现在接受并默认为 None 以使用适当的默认值。

3.6 版更改: dir 参数现在接受 类路径对象

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

以最安全的方式创建临时目录。 目录的创建中没有竞争条件。 该目录只能通过创建用户 ID 进行读取、写入和搜索。

mkdtemp() 的用户负责删除临时目录及其内容。

prefixsuffixdir 参数与 mkstemp() 的参数相同。

mkdtemp() 返回新目录的绝对路径名。

在 3.5 版中更改:suffixprefixdir 现在可以以字节为单位提供,以获得字节返回值。 在此之前,只允许 str 。 suffixprefix 现在接受并默认为 None 以使用适当的默认值。

3.6 版更改: dir 参数现在接受 类路径对象

tempfile.gettempdir()

返回用于临时文件的目录的名称。 这定义了此模块中所有函数的 dir 参数的默认值。

Python 搜索标准目录列表以查找调用用户可以在其中创建文件的目录。 名单是:

  1. TMPDIR 环境变量命名的目录。

  2. TEMP 环境变量命名的目录。

  3. TMP 环境变量命名的目录。

  4. 特定于平台的位置:

    • 在 Windows 上,目录 C:\TEMPC:\TMP\TEMP\TMP,按此顺序。

    • 在所有其他平台上,目录 /tmp/var/tmp/usr/tmp,按此顺序。

  5. 作为最后的手段,当前工作目录。

这个搜索的结果被缓存,见下面tempdir的描述。

在 3.10 版更改: 始终返回一个 str。 以前它会返回任何 tempdir 值,而不管类型如何,只要它不是 None

tempfile.gettempdirb()

gettempdir() 相同,但返回值以字节为单位。

3.5 版中的新功能。

tempfile.gettempprefix()
返回用于创建临时文件的文件名前缀。 这不包含目录组件。
tempfile.gettempprefixb()

gettempprefix() 相同,但返回值以字节为单位。

3.5 版中的新功能。

该模块使用一个全局变量来存储用于由 gettempdir() 返回的临时文件的目录名称。 它可以直接设置为覆盖选择过程,但不鼓励这样做。 此模块中的所有函数都采用 dir 参数,该参数可用于指定目录。 这是推荐的方法,不会通过更改全局 API 行为来让其他毫无戒心的代码感到惊讶。

tempfile.tempdir

当设置为 None 以外的值时,此变量定义了此模块中定义的函数的 dir 参数的默认值,包括其类型、字节或 str。 它不能是 类路径对象

如果 tempdirNone(默认值)在对上述任何函数的任何调用中,除了 gettempprefix(),它按照 gettempdir( )

笔记

请注意,如果将 tempdir 设置为字节值,则会产生令人讨厌的副作用:mkstemp()mkdtemp() 的全局默认返回类型更改为未提供 str 类型的显式 prefixsuffixdir 参数时的字节数。 请不要编写期望或依赖于此的代码。 保持这种尴尬的行为是为了与历史实现兼容。

例子

以下是 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()

返回调用时不存在的文件的绝对路径名。 prefixsuffixdir 参数与 mkstemp() 的参数类似,除了字节文件名 suffix=Noneprefix=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