生成临时文件名而无需在Python中创建实际文件

Hil*_*ill 71 python temporary-files

stackoverflow中的问题编号10501247给出了如何在Python中创建临时文件的答案.
在我的情况下,我只需要有临时文件名.
调用tempfile.NamedTemporaryFile()会在实际创建文件后返回文件句柄.
有办法获取文件名吗?

# Trying to get temp file path
tf = tempfile.NamedTemporaryFile()
temp_file_name = tf.name
tf.close()
# Here is my real purpose to get the temp_file_name
f = gzip.open(temp_file_name ,'wb')
...
Run Code Online (Sandbox Code Playgroud)

Mar*_*cin 55

如果只想要临时文件名,可以调用内部tempfile函数_get_candidate_names():

import tempfile

temp_name = next(tempfile._get_candidate_names())
% e.g. px9cp65s
Run Code Online (Sandbox Code Playgroud)

next再次调用,将返回另一个名称等.这不会为您提供临时文件夹的路径.要获取默认的'tmp'目录,请使用:

defult_tmp_dir = tempfile._get_default_tempdir()
% results in: /tmp 
Run Code Online (Sandbox Code Playgroud)

  • 需要指出的是,`next(tempfile._get_candidate_names())` 不一定返回不存在的路径,这就是为什么用户级临时文件接口可以[尝试多个名称,直到找到一个未使用的名称](https:// github.com/python/cpython/blob/cafaf0447b950fd4f59edd8cbde040c61ae528f8/Lib/tempfile.py#L255): (4认同)
  • 更好的创建临时目录的方法是`temp_dir = tempfile.mkdtemp(prefix ='some-prefix _')`这将安全地创建一个临时目录并返回一个带有绝对路径的字符串. (3认同)
  • 可以使用公共的`tempfile.gettempdir()` 而不是私有的`tempfile._get_default_tempdir()`。 (2认同)

Ale*_*lec 29

我认为最简单,最安全的方法是这样的:

path = os.path.join(tempfile.mkdtemp(), 'something')
Run Code Online (Sandbox Code Playgroud)

创建只有您可以访问的临时目录,因此不存在安全问题,但不会在其中创建任何文件,因此您只需选择要在该目录中创建的任何文件名.

  • 如果您使用 tempfile.TemporaryDirectory() 作为上下文管理器,它将被删除。 (8认同)
  • 我真的很喜欢这个,因为它会自动处理删除。就我而言,为 Shutil.make_archive 函数创建临时文件名很有用,因为它需要存档的基本名称作为输入,而不是类似文件的对象。 (2认同)

rus*_*ell 12

可能有点晚了,但这有什么不对吗?

import tempfile
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as tmpfile:
    temp_file_name = tmpfile.name
f = gzip.open(temp_file_name ,'wb')
Run Code Online (Sandbox Code Playgroud)

  • 这段代码实际上会创建临时文件以获取其名称,而在问题中它表示"不在Python中创建实际文件". (27认同)
  • 这并不能回答问题 (3认同)

Ada*_*ski 8

我们尽量不要想太多:

import os, uuid, tempfile as tf

def make_temp_name(dir = tf.gettempdir()):
    return os.path.join(dir, str(uuid.uuid1()))
Run Code Online (Sandbox Code Playgroud)


Zit*_*rax 7

tempfile.mktemp() 做这个.

但请注意,它已被弃用.但是它不会创建文件,并且与使用文件相比,它是tempfile中的公共函数_get_candidate_names().

它被弃用的原因是由于调用它和实际尝试创建文件之间的时间差.然而在我的情况下,这种情况的可能性非常小,即使它会失败也是可以接受的.但是由你来评估你的用例.

  • @bignose这是*潜在的*安全问题.这取决于你想做什么,你所处的执行环境等等.那说:做一些像`os.path.join(tempfile.mkdtemp(),'something')这样的东西可能更安全.至少目录是创建的(并且由我自己拥有,我推测). (4认同)

PM *_*ing 5

正如 Joachim Isaksson 在评论中所说,如果您只是获得一个名称,如果其他程序碰巧在您的程序之前使用该名称,则可能会遇到问题。机会很小,但并非不可能。

因此,在这种情况下,安全的做法是使用完整的GzipFile()构造函数,它具有签名

GzipFile( [filename[, mode[, compresslevel[, fileobj]]]])
Run Code Online (Sandbox Code Playgroud)

因此,如果您愿意,您可以将打开的文件对象和文件名传递给它。有关详细信息,请参阅gzip 文档


jua*_*cks 5

结合之前的答案,我的解决方案是:

def get_tempfile_name(some_id):
    return os.path.join(tempfile.gettempdir(), next(tempfile._get_candidate_names()) + "_" + some_id)
Run Code Online (Sandbox Code Playgroud)

some_id如果您不需要,请将其设为可选。


use*_*723 5

我会这样做:

import tempfile
import os.path
import random
import string

def generate_temp_filename() -> str:
    random_string = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
    return os.path.join(tempfile.gettempdir(), random_string)
Run Code Online (Sandbox Code Playgroud)

相对于其他答案的优势:

  • 不依赖私有函数(以 开头的函数_
  • 不创建文件或目录
  • 不使用已弃用的函数