Pythonでランダムなファイル名を生成する最良の方法


95

Pythonでは、サーバーに保存するファイル(名前)の前に追加するランダムテキストを生成して、上書きしないことを確認するための良い方法、または最良の方法は何ですか。ありがとうございました!

回答:


109

Pythonには一時ファイル名を生成する機能があります。http://docs.python.org/library/tempfile.htmlを参照してください。例えば:

In [4]: import tempfile

を呼び出すたびに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'

一意のファイル名を取得すると、通常のファイルと同じように使用できます。:デフォルトでは、ファイルを閉じると削除されます。ただし、deleteパラメーターがFalseの場合、ファイルは自動的に削除されません。

完全なパラメータセット:

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

一時ファイルの接頭辞を指定することもできます(ファイルの作成時に指定できるさまざまなパラメーターの1つとして)。

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

一時ファイルを操作するための追加の例はここにあります


1
次にマシンを再起動したときに、これらのファイルは削除されますか?
HelloWorld 2016年

14
このソリューションの問題は、ファイル名だけでなく、すでに開いているファイルも生成することです。まだ存在していない新しいファイルの一時ファイル名が必要な場合(たとえば、osコマンドの出力として使用する場合)、これは機能しません。その場合、str(uuid.uuid4())のようなことができます。
Luca

@Luca追加のコメントをありがとう、それは便利であり、将来の参照のために注記されています。ただし、OPはファイルを保存する必要があるため、ファイルを開く必要があることを明確に述べているため、このソリューションではそれを提供しています。
Levon 2016

場合によります。おそらく、彼は適切なサーバー呼び出しを作成するために名前が必要です。わからない。とにかく、あなたの返答は確かにより一般的なケースです。
Luca

104

ランダムな文字列を生成するためにUUIDモジュールを使用できます:

import uuid
filename = str(uuid.uuid4())

UUIDジェネレーターが重複した識別子(この場合はファイル名)を生成する可能性が非常に低いことを考えると、これは有効な選択です。

次の100年間、毎秒10億個のUUIDを生成して初めて、複製が1つだけ作成される確率は約50%になります。地球上のすべての人が6億のUUIDを所有している場合、1つの重複の確率は約50%になります。


16
これは、一意のファイル名が必要で、まだ作成したくない場合にも非常に便利です。
Falken教授、2013年

14
またはuuid.uuid4().hex、ダッシュなしの16進文字列を取得するために使用します(-)。
Rockallite 2015年

17

一般的なアプローチは、ファイル名にプレフィックス/サフィックスとしてタイムスタンプを追加して、ファイルとの一時的な関係を持たせることです。さらに一意性が必要な場合でも、ランダムな文字列を追加できます。

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

4
マルチスレッド環境では、シーケンスに関連する可能性のある競合状態が発生します1. Test if file exists, 2. create file.。別のプロセスがステップ1と2の間に割り込み、ファイルを作成した場合、コードが再開すると、他のプロセスのファイルが上書きされます。
Li-aung Yip、2012

@ Li-aungYipさらに、6〜8個のランダムな文字シーケンスを使用することもできます(同じ秒に2つのファイルが生成される場合)。
bobobobo 2013

@bobobobo:またはtempfile、これを処理するモジュールを使用できます。:)
Li-aung Yip 2013

マイクロ秒を追加することをお勧めします。すなわち...strftime("%y%m%d_%H%M%S%f")
AstraSerg

8

OPは、ランダムファイルではなくランダムファイルを作成するように要求しました。時間とUUIDが衝突する可能性があります。単一のマシン(共有ファイルシステムではない)で作業していて、プロセス/スレッドがそれ自体で踏みつけない場合は、os.getpid()を使用して独自のPIDを取得し、これを一意のファイル名の要素として使用します。他のプロセスは明らかに同じPIDを取得しません。マルチスレッドの場合は、スレッドIDを取得します。単一のスレッドまたはプロセスが複数の異なる一時ファイルを生成する可能性があるコードの他の側面がある場合は、別の手法を使用する必要がある場合があります。ローリングインデックスは機能します(あまり長く保持しない場合、または非常に多くのファイルを使用する場合は、ロールオーバーが心配になります)。その場合、「アクティブ」ファイルへのグローバルハッシュ/インデックスを保持するだけで十分です。

長い説明で申し訳ありませんが、実際の使用方法によって異なります。


8

ファイルパスが必要なく、事前に定義された長さのランダムな文字列のみが必要な場合は、このようなものを使用できます。

>>> import random
>>> import string

>>> file_name = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
>>> file_name
'ytrvmyhkaxlfaugx'

7

元のファイル名を新しいファイル名の一部として保持したい場合は、現在の時刻のMD5ハッシュを使用して、長さが一定の一意のプレフィックスを生成できます。

from hashlib import md5
from time import localtime

def add_prefix(filename):
    prefix = md5(str(localtime()).encode('utf-8')).hexdigest()
    return f"{prefix}_{filename}"

add_prefix( 'style.css')を呼び出すと、次のようなシーケンスが生成されます。

a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css

1
回避するには:ハッシュする前にUnicodeオブジェクトをエンコードする必要がありますmd5(str(localtime())。encode( 'utf-8'))。hexdigest()
PhoebeB

1
任意の種類のデータ(タイムスタンプを含む)のハッシュは、それ自体では一意性を保証しないことに注意してください(ランダムに選択されたバイトシーケンス以上のものはありません)。
ピーターO.

1

ここに私の2セントを追加します。

In [19]: tempfile.mkstemp('.png', 'bingo', '/tmp')[1]
Out[19]: '/tmp/bingoy6s3_k.png'

tempfile.mkstempのPythonドキュメントによると、可能な限り最も安全な方法で一時ファイルを作成します。この呼び出しの後にファイルが存在することに注意してください:

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

1

私は個人的に自分のテキストをランダム/一意であるだけでなく美しいものにすることを好みます。そのため、私はhashids libが好きです。これは、整数から見栄えの良いランダムテキストを生成します。を通じてインストールできます

pip install hashids

スニペット:

import hashids
hashids = hashids.Hashids(salt="this is my salt", )
print hashids.encode(1, 2, 3)
>>> laHquq

簡単な説明:

Hashidsは小さなオープンソースライブラリで、数字から短くて一意の非連続IDを生成します。


0
>>> import random
>>> import string    
>>> alias = ''.join(random.choice(string.ascii_letters) for _ in range(16))
>>> alias
'WrVkPmjeSOgTmCRG'

「string.ascii_letters」を任意の文字列形式に変更して、モバイルNO、IDなどの他のテキストを生成できます。 ここに画像の説明を入力してください


0
import uuid
   imageName = '{}{:-%Y%m%d%H%M%S}.jpeg'.format(str(uuid.uuid4().hex), datetime.now())

1
このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、投票数が増える可能性があります。あなたが今尋ねている人だけでなく、将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。
БогданОпир

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.