Cara terbaik untuk menghasilkan nama file acak dengan Python

97

Di Python, apa yang baik, atau cara terbaik untuk menghasilkan beberapa teks acak untuk ditambahkan ke file (nama) yang saya simpan ke server, hanya untuk memastikannya tidak menimpa. Terima kasih!

zallarak
sumber

Jawaban:

109

Python memiliki fasilitas untuk menghasilkan nama file sementara, lihat http://docs.python.org/library/tempfile.html . Misalnya:

In [4]: import tempfile

Setiap panggilan tempfile.NamedTemporaryFile()menghasilkan file temp yang berbeda, dan namanya dapat diakses dengan .nameatribut, misalnya:

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'

Setelah Anda memiliki nama file yang unik, itu dapat digunakan seperti file biasa. Catatan : Secara default, file akan dihapus saat ditutup. Namun, jika deleteparameternya False, file tersebut tidak otomatis dihapus.

Set parameter lengkap:

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

Anda juga dapat menentukan awalan untuk file sementara (sebagai salah satu dari berbagai parameter yang dapat diberikan selama pembuatan file):

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

Contoh tambahan untuk bekerja dengan file sementara dapat ditemukan di sini

Levon
sumber
1
Apakah file-file itu akan dihapus saat saya me-restart komputer saya?
HelloWorld
15
Masalah dengan solusi ini adalah ia menghasilkan tidak hanya nama file, tetapi juga file yang sudah terbuka. Jika Anda memerlukan nama file sementara untuk file baru, yang belum ada (misalnya, untuk digunakan sebagai output dari perintah os), ini tidak akan dilakukan. Dalam hal ini, Anda dapat melakukan sesuatu seperti str (uuid.uuid4 ()).
Luca
@Luca Terima kasih atas komentar tambahan, yang berguna, dan dicatat untuk referensi di masa mendatang. Namun, OP dengan jelas menyatakan bahwa dia ingin menyimpan file, maka perlu membukanya, jadi solusi ini menyediakannya.
Levon
Tergantung. Mungkin dia membutuhkan nama tersebut untuk membuat panggilan server yang sesuai. Tidak yakin. Bagaimanapun, jawaban Anda tentu merupakan kasus yang lebih umum.
Luca
108

Anda dapat menggunakan modul UUID untuk membuat string acak:

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

Ini adalah pilihan yang valid, mengingat generator UUID sangat tidak mungkin menghasilkan pengenal duplikat (dalam hal ini nama file):

Hanya setelah menghasilkan 1 miliar UUID setiap detik selama 100 tahun ke depan, kemungkinan membuat hanya satu duplikat akan menjadi sekitar 50%. Kemungkinan satu duplikat akan menjadi sekitar 50% jika setiap orang di bumi memiliki 600 juta UUID.

Óscar López
sumber
17
ini juga sangat berguna jika Anda menginginkan nama file yang unik, tetapi belum ingin membuatnya.
Prof. Falken
15
Atau gunakan uuid.uuid4().hexuntuk mendapatkan string hex tanpa tanda hubung ( -).
Rockallite
17

pendekatan yang umum adalah menambahkan stempel waktu sebagai awalan / akhiran ke nama file agar memiliki beberapa hubungan temporal ke file. Jika Anda membutuhkan lebih banyak keunikan, Anda masih dapat menambahkan string acak ke dalamnya.

import datetime
basename = "mylogfile"
suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
filename = "_".join([basename, suffix]) # e.g. 'mylogfile_120508_171442'
moooeeeep
sumber
4
Dalam lingkungan multi-utas, ada kemungkinan kondisi balapan yang terlibat dalam urutan 1. Test if file exists, 2. create file.Jika proses lain mengganggu Anda antara langkah 1 dan 2, dan membuat file, ketika kode Anda dilanjutkan, itu akan menimpa file proses lainnya.
Li-aung Yip
@ Li-aungYip Selain itu juga dapat menggunakan 6-8 urutan karakter acak (dalam kasus 2 file dihasilkan dalam detik yang sama).
bobobobo
@bobobobo: Atau Anda dapat menggunakan tempfilemodul, yang menangani ini untuk Anda. :)
Li-aung Yip
Saya menyarankan untuk menambahkan mikrodetik yaitu...strftime("%y%m%d_%H%M%S%f")
AstraSerg
8

OP meminta untuk membuat nama file acak, bukan file acak . Waktu dan UUID bisa bertabrakan. Jika Anda bekerja pada satu mesin (bukan sistem file bersama) dan proses / utas Anda tidak akan menginjak dirinya sendiri, gunakan os.getpid () untuk mendapatkan PID Anda sendiri dan gunakan ini sebagai elemen dari nama file unik. Proses lain jelas tidak akan mendapatkan PID yang sama. Jika Anda multithread, dapatkan id thread. Jika Anda memiliki aspek lain dari kode Anda di mana satu utas atau proses dapat menghasilkan beberapa file temporer yang berbeda, Anda mungkin perlu menggunakan teknik lain. Indeks bergulir dapat berfungsi (jika Anda tidak menyimpannya terlalu lama atau menggunakan begitu banyak file, Anda akan khawatir tentang rollover). Menjaga hash / indeks global ke file "aktif" akan cukup dalam kasus itu.

Mohon maaf atas penjelasan jangka panjangnya, tetapi itu tergantung pada penggunaan persis Anda.

Brad
sumber
8

Jika Anda tidak memerlukan jalur file, tetapi hanya string acak yang memiliki panjang yang telah ditentukan, Anda dapat menggunakan sesuatu seperti ini.

>>> import random
>>> import string

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

Jika Anda ingin mempertahankan nama file asli sebagai bagian dari nama file baru, awalan unik dengan panjang seragam dapat dibuat dengan menggunakan hash MD5 waktu saat ini:

from hashlib import md5
from time import localtime

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

Panggilan ke add_prefix ('style.css') menghasilkan urutan seperti:

a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css
Aleš Kotnik
sumber
1
Untuk menghindari: Unicode-objek harus dikodekan sebelum hashing Saya berubah menjadi md5 (str (localtime ()). Encode ('utf-8')). Hexdigest ()
PhoebeB
1
Perhatikan bahwa hash dari semua jenis data (termasuk stempel waktu) tidak memastikan keunikan dengan sendirinya (lebih dari urutan byte yang dipilih secara acak).
Peter O.
1

Menambahkan dua sen saya di sini:

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

Menurut python doc untuk tempfile.mkstemp, ini membuat file sementara dengan cara yang paling aman. Harap dicatat bahwa file akan ada setelah panggilan ini:

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

Saya pribadi lebih suka teks saya tidak hanya acak / unik tetapi juga indah, itulah mengapa saya menyukai hashids lib, yang menghasilkan teks acak yang tampak bagus dari integer. Dapat diinstal melalui

pip install hashids

Potongan:

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

Deskripsi Singkat:

Hashids adalah pustaka sumber terbuka kecil yang menghasilkan id pendek, unik, dan tidak berurutan dari angka.

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

Anda dapat mengubah 'string.ascii_letters' ke format string apa pun yang Anda inginkan untuk menghasilkan teks lain, misalnya NO seluler, ID ... masukkan deskripsi gambar di sini

Freman Zhang
sumber
0
import uuid
   imageName = '{}{:-%Y%m%d%H%M%S}.jpeg'.format(str(uuid.uuid4().hex), datetime.now())
Asad Farooq
sumber
1
Meskipun kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan memberikan indikasi batasan dan asumsi apa yang berlaku.
Богдан Опир
-1

Anda bisa menggunakan paket acak:

import random
file = random.random()
anajem
sumber
file = str (random.random ())
anajem
Ini menghasilkan angka acak, bukan teks acak.
pengguna1767754