在Python中生成随机文件名的最佳方法

zal*_*rak 87 python random hash

在Python中,生成一些随机文本以预先添加到我保存到服务器的文件(名称)的最佳方法是什么,只是为了确保它不会覆盖.谢谢!

Lev*_*von 99

Python具有生成临时文件名的功能,请参阅http://docs.python.org/library/tempfile.html.例如:

In [4]: import tempfile
Run Code Online (Sandbox Code Playgroud)

每次调用都会生成tempfile.NamedTemporaryFile()一个不同的临时文件,并且可以使用该.name属性访问其名称,例如:

In [5]: tf = tempfile.NamedTemporaryFile()
In [6]: tf.name
Out[6]: 'c:\\blabla\\locals~1\\temp\\tmptecp3i'

In [7]: tf = tempfile.NamedTemporaryFile()
In [8]: tf.name
Out[8]: 'c:\\blabla\\locals~1\\temp\\tmpr8vvme'
Run Code Online (Sandbox Code Playgroud)

一旦拥有唯一的文件名,就可以像任何常规文件一样使用它.注意:默认情况下,文件将在关闭时删除.但是,如果delete参数为False,则不会自动删除该文件.

完整参数集:

tempfile.NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None[, delete=True]]]]]])
Run Code Online (Sandbox Code Playgroud)

也可以指定临时文件的前缀(作为文件创建期间可以提供的各种参数之一):

In [9]: tf = tempfile.NamedTemporaryFile(prefix="zz")
In [10]: tf.name
Out[10]: 'c:\\blabla\\locals~1\\temp\\zzrc3pzk'
Run Code Online (Sandbox Code Playgroud)

可以在此处找到使用临时文件的其他示例

  • 此解决方案的问题在于它不仅生成文件名,还生成已打开的文件.如果您需要一个新的,尚未存在的文件的临时文件名(例如,用作os命令的输出),这将不起作用.在这种情况下,您可以执行类似str(uuid.uuid4())的操作. (8认同)

Ósc*_*pez 90

您可以使用UUID模块生成随机字符串:

import uuid
filename = str(uuid.uuid4())
Run Code Online (Sandbox Code Playgroud)

这是一个有效的选择,因为UUID生成器极不可能产生重复的标识符(在这种情况下是文件名):

只有在接下来的100年中每秒产生10亿UUID之后,仅创建一个副本的概率大约为50%.如果地球上每个人拥有6亿UUID,则一次重复的概率约为50%.

  • 当你想要一个唯一的文件名但不想创建它时,这也非常有用. (15认同)
  • 或者使用`uuid.uuid4().hex`来获得不带破折号的十六进制字符串(`-`). (11认同)

moo*_*eep 16

一种常见的方法是将时间戳添加为文件名的前缀/后缀,以与文件建立时间关系.如果您需要更多唯一性,您仍然可以为此添加随机字符串.

import datetime
basename = "mylogfile"
suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
filename = "_".join([basename, suffix]) # e.g. 'mylogfile_120508_171442'
Run Code Online (Sandbox Code Playgroud)

  • 在多线程环境中,序列`1中可能存在竞争条件.测试文件是否存在,2.创建文件.如果另一个进程在步骤1和2之间中断,并创建文件,当代码恢复时,它将覆盖另一个进程的文件. (4认同)
  • 我建议添加微秒,即 `...strftime("%y%m%d_%H%M%S%f")` (2认同)

Bra*_*rad 8

OP要求创建随机文件名而不是随机文件.时代和UUID可能会发生冲突.如果您正在使用单个计算机(而不是共享文件系统)并且您的进程/线程不会踩踏自己,请使用os.getpid()获取您自己的PID并将其用作唯一文件名的元素.其他过程显然不会得到相同的PID.如果您是多线程的,请获取线程ID.如果您的代码的其他方面中单个线程或进程可以生成多个不同的临时文件,则可能需要使用其他技术.滚动索引可以工作(如果你没有保持这么长时间或使用这么多文件你会担心翻转).在这种情况下,将全局哈希/索引保持为"活动"文件就足够了.

很抱歉这个长篇大论的解释,但这取决于你的确切用法.


4xy*_*4xy 7

如果您不需要文件路径,而只需要具有预定义长度的随机字符串,则可以使用类似的内容。

>>> import random
>>> import string

>>> file_name = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
>>> file_name
'ytrvmyhkaxlfaugx'
Run Code Online (Sandbox Code Playgroud)


Ale*_*nik 5

如果要将原始文件名保留为新文件名的一部分,则可以通过以下方式生成unifom长度的唯一前缀:

def add_prefix(filename):

  from hashlib import md5
  from time import localtime

  return "%s_%s" % (md5(str(localtime())).hexdigest(), filename)
Run Code Online (Sandbox Code Playgroud)

调用àdd_prefix('style.css')会生成如下序列:

a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css
Run Code Online (Sandbox Code Playgroud)


sha*_*ins 5

在这里添加我的两分钱:

In [19]: tempfile.mkstemp('.png', 'bingo', '/tmp')[1]
Out[19]: '/tmp/bingoy6s3_k.png'
Run Code Online (Sandbox Code Playgroud)

根据 tempfile.mkstemp 的 python 文档,它以最安全的方式创建临时文件。请注意,该文件将在此调用后存在:

In [20]: os.path.exists(tempfile.mkstemp('.png', 'bingo', '/tmp')[1])
Out[20]: True
Run Code Online (Sandbox Code Playgroud)