Python'da rastgele dosya adları oluşturmanın en iyi yolu


100

Python'da, sadece üzerine yazmadığından emin olmak için, bir sunucuya kaydettiğim bir dosyanın (adın) başına rastgele bir metin oluşturmanın iyi veya en iyi yolu nedir? Teşekkür ederim!

Yanıtlar:


112

Python, geçici dosya adları oluşturma olanaklarına sahiptir, bkz. Http://docs.python.org/library/tempfile.html . Örneğin:

In [4]: import tempfile

Her çağrı, tempfile.NamedTemporaryFile()farklı bir geçici dosya ile sonuçlanır ve adına, .nameöznitelikle erişilebilir , örneğin:

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'

Benzersiz dosya adına sahip olduğunuzda, herhangi bir normal dosya gibi kullanılabilir. Not : Varsayılan olarak dosya kapatıldığında silinecektir . Bununla birlikte, deleteparametre False ise, dosya otomatik olarak silinmez.

Tam parametre seti:

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

geçici dosya için ön ek de belirtilebilir (dosya oluşturma sırasında sağlanabilecek çeşitli parametrelerden biri olarak):

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

Geçici dosyalarla çalışmak için ek örnekler burada bulunabilir


1
Makinemi bir dahaki sefer yeniden başlattığımda bu dosyalar silinir mi?
SmallChess

17
Bu çözümle ilgili sorun, yalnızca bir dosya adı değil, aynı zamanda zaten açık olan bir dosya oluşturmasıdır. Yeni, henüz mevcut olmayan bir dosya için geçici bir dosya adına ihtiyacınız varsa (örneğin, bir os komutunun çıktısı olarak kullanmak için), bu işe yaramayacaktır. Bu durumda str (uuid.uuid4 ()) gibi bir şey yapabilirsiniz.
Luca

@Luca Faydalı olan ek yorum için teşekkürler ve ileride başvurmak üzere not edildi. Ancak OP, bir dosyayı kaydetmek istediğini, dolayısıyla açması gerektiğini, dolayısıyla bu çözümün bunu sağladığını açıkça belirtmiştir.
Levon

Değişir. Belki de uygun bir sunucu çağrısı oluşturmak için isme ihtiyacı vardır. Emin değil. Her halükarda cevabınız kesinlikle daha yaygın bir durumdur.
Luca

115

Rastgele bir dizi oluşturmak için UUID modülünü kullanabilirsiniz :

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

Bu, bir UUID oluşturucunun yinelenen bir tanımlayıcı (bu durumda bir dosya adı) üretme ihtimalinin son derece düşük olduğu göz önüne alındığında geçerli bir seçimdir :

Ancak önümüzdeki 100 yıl boyunca her saniye 1 milyar UUID oluşturduktan sonra, yalnızca bir kopya oluşturma olasılığı yaklaşık% 50 olacaktır. Yeryüzündeki her insan 600 milyon UUID'ye sahipse, bir kopya olasılığı yaklaşık% 50 olacaktır.


18
Bu, benzersiz bir dosya adı istediğinizde, ancak henüz oluşturulmasını istemediğinizde de çok kullanışlıdır.
Prof. Falken

16
Veya uuid.uuid4().hextire ( -) içermeyen bir onaltılık dize elde etmek için kullanın .
Rockallite

17

Yaygın bir yaklaşım, dosyayla bazı geçici ilişkilere sahip olmak için dosya adına önek / sonek olarak bir zaman damgası eklemektir. Daha fazla benzersizliğe ihtiyacınız varsa, buna yine de rastgele bir dize ekleyebilirsiniz.

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
Çok iş parçacıklı bir ortamda, dizide olası bir yarış koşulu vardır. 1. Test if file exists, 2. create file.Başka bir işlem, 1. ve 2. adımlar arasında sizinkini kesintiye uğratırsa ve dosyayı oluşturur, kodunuz devam ettiğinde diğer işlemin dosyasının üzerine yazacaktır.
Li-aung Yip

@ Li-aungYip Ayrıca 6-8 rastgele karakter dizisi kullanabilir (aynı saniyede 2 dosya üretilmesi durumunda).
bobobobo

@bobobobo: Ya da bunu sizin için halleden tempfilemodülü kullanabilirsiniz . :)
Li-aung Yip

Mikrosaniye eklemenizi öneririm, yani...strftime("%y%m%d_%H%M%S%f")
AstraSerg

8

OP, rastgele dosyalar değil, rastgele dosya adları yaratmayı talep etti . Zamanlar ve UUID'ler çakışabilir. Tek bir makinede (paylaşılan bir dosya sisteminde değil) çalışıyorsanız ve işleminiz / iş parçacığınız kendi başına durmuyorsa, kendi PID'nizi almak için os.getpid () kullanın ve bunu benzersiz bir dosya adının bir öğesi olarak kullanın. Diğer süreçler açıkça aynı PID'yi almayacaktır. Çok iş parçacıklıysanız, iş parçacığı kimliğini alın. Tek bir iş parçacığının veya işlemin birden çok farklı geçici dosya oluşturabileceği kodunuzun başka yönlerine sahipseniz, başka bir teknik kullanmanız gerekebilir. Dönen bir dizin işe yarayabilir (onları çok uzun tutmuyorsanız veya çok fazla dosya kullanmıyorsanız, rollover hakkında endişelenirsiniz). Bu durumda "aktif" dosyalar için global bir hash / index tutmak yeterli olacaktır.

Uzun soluklu açıklama için özür dilerim, ancak bu tam kullanımınıza bağlı.


8

Dosya yoluna ihtiyacınız yoksa, ancak yalnızca önceden tanımlanmış uzunluğa sahip rastgele dizeye ihtiyacınız varsa, bunun gibi bir şey kullanabilirsiniz.

>>> import random
>>> import string

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

7

Orijinal dosya adını yeni dosya adının bir parçası olarak korumak isterseniz, geçerli zamanın MD5 karmaları kullanılarak tek tip uzunlukta benzersiz önekler oluşturulabilir:

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') çağrısı, aşağıdaki gibi bir sıra oluşturur:

a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css

1
Önlemek için: Unicode nesneleri Değiştim karma önce kodlanmış olmalıdır için md5 (str (localtime ()) kodlamak ( 'utf-8').) Hexdigest ().
PhoebeB

1
Herhangi bir veri türünün karma değerinin (bir zaman damgası dahil) kendi başına benzersizliği sağlamadığını unutmayın (rastgele seçilen bir bayt dizisinden daha fazla).
Peter O.

1

İki sentimi buraya eklemek:

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

Tempfile.mkstemp için python belgesine göre, mümkün olan en güvenli şekilde geçici bir dosya oluşturur. Lütfen dosyanın bu görüşmeden sonra var olacağını unutmayın:

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

1

Ben şahsen metnimin sadece rastgele / benzersiz değil aynı zamanda güzel olmasını tercih ederim, bu yüzden tamsayılardan hoş görünümlü rastgele metin oluşturan hashids lib'i seviyorum. Aracılığıyla kurulabilir

pip install hashids

Snippet:

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

Kısa Açıklama:

Hashids, sayılardan kısa, benzersiz, sıralı olmayan kimlikler üreten küçük bir açık kaynaklı kitaplıktır.


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

'String.ascii_letters' herhangi başka bir metin oluşturmak istediğinizde herhangi bir dize biçimine değiştirebilirsiniz, örneğin mobile NO, ID ... görüntü açıklamasını buraya girin


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

1
Bu kod soruyu çözebilirken, sorunun nasıl ve neden çözüldüğüne dair bir açıklama da dahil olmak üzere , gönderinizin kalitesini artırmaya gerçekten yardımcı olur ve muhtemelen daha fazla oy almanıza neden olur. Sadece şimdi soran kişi için değil, gelecekte okuyucular için soruyu yanıtladığınızı unutmayın. Açıklamalar eklemek ve hangi sınırlamaların ve varsayımların geçerli olduğuna dair bir gösterge vermek için lütfen yanıtınızı düzenleyin .
Богдан Опир

-1

Rastgele paketi kullanabilirsiniz:

import random
file = random.random()

dosya = str (random.random ())
anajem

Bu, rastgele bir metin değil, rastgele sayılar üretir.
user1767754
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.