Python: Bagaimana cara membuat nama file yang unik?


95

Saya memiliki formulir web python dengan dua opsi - Unggah file dan textarea . Saya perlu mengambil nilai dari masing-masing dan meneruskannya ke program baris perintah lain. Saya dapat dengan mudah mengirimkan nama file dengan opsi unggah file, tetapi saya tidak yakin bagaimana cara melewatkan nilai textarea.

Saya pikir yang perlu saya lakukan adalah:

  1. Buat nama file yang unik
  2. Buat file sementara dengan nama itu di direktori kerja
  3. Simpan nilai yang diteruskan dari textarea ke file sementara
  4. Jalankan program baris perintah dari dalam modul python saya dan berikan nama file sementara

Saya tidak yakin bagaimana cara menghasilkan nama file yang unik. Adakah yang bisa memberi saya beberapa tip tentang cara menghasilkan nama file yang unik? Algoritme, saran, dan baris kode apa pun dihargai.

Terima kasih atas perhatianmu


1
Saya mengedit pertanyaan Anda untuk mencoba membuatnya lebih jelas. Beri tahu saya jika saya menafsirkan sesuatu dengan tidak benar!
culix

Jawaban:


147

Saya tidak berpikir pertanyaan Anda sangat jelas, tetapi jika yang Anda butuhkan hanyalah nama file yang unik ...

import uuid

unique_filename = str(uuid.uuid4())

Maaf saya bekerja pada platform windows jadi tidak tahu bagaimana menangani subproses
MysticCodes

uuid sepertinya membuat string unik yang panjang. Saya tidak berpikir lebih baik memiliki nama file dengan string panjang dan UUID, () di dalamnya.
MysticCodes

6
Saya pikir uuid.uuid4().hexakan menjadi pilihan yang lebih baik, lihat detailnya di sini .
Gray Li

4
@ToloPalmer: Kemungkinan besar CPU komputer Anda mengalami kesalahan pemrosesan yang menyebabkannya memuat file yang salah daripada UUID yang dihasilkan bertabrakan dengan nilai yang ada. UUID menghasilkan nama unik dalam model komputasi yang memahami bahwa tidak semua komputasi adalah matematika murni.
GManNickG

2
Maafkan ketidaktahuan saya komentar lama ... Memang tidak unik tapi sangat tidak mungkin bertabrakan, jadi pilihan yang bagus;)
Tolo Palmer

51

Jika Anda ingin membuat file sementara dengan Python, ada modul bernama tempfile di pustaka standar Python. Jika Anda ingin meluncurkan program lain untuk mengoperasikan file, gunakan tempfile.mkstemp () untuk membuat file, dan os.fdopen () untuk mengakses deskriptor file yang diberikan mkstemp () kepada Anda.

Kebetulan, Anda mengatakan Anda menjalankan perintah dari program Python? Anda hampir pasti harus menggunakan modul subprocess .

Jadi Anda dapat dengan senang hati menulis kode yang terlihat seperti:

import subprocess
import tempfile
import os

(fd, filename) = tempfile.mkstemp()
try:
    tfile = os.fdopen(fd, "w")
    tfile.write("Hello, world!\n")
    tfile.close()
    subprocess.Popen(["/bin/cat", filename]).wait()        
finally:
    os.remove(filename)

Dengan menjalankan itu, Anda akan menemukan bahwa catperintah tersebut bekerja dengan baik, tetapi file sementara telah dihapus di finallyblok tersebut. Sadarilah bahwa Anda harus menghapus file sementara yang mkstemp () kembalikan sendiri - perpustakaan tidak memiliki cara untuk mengetahui kapan Anda selesai dengan itu!

(Sunting: Saya telah berasumsi bahwa NamedT TemporaryFile melakukan apa yang Anda cari, tetapi itu mungkin tidak begitu nyaman - file akan segera dihapus ketika objek file temp ditutup, dan memiliki proses lain membuka file sebelum Anda menutupnya tidak akan berfungsi pada beberapa platform, terutama Windows. Maaf, saya gagal.)


menggunakan NamedT TemporaryFile mungkin adalah yang mereka inginkan (kecuali mereka ingin tetap berada di server, dan kemudian mereka dapat menggunakan "tempfile.NamedT TemporaryFile (delete = False)")
Terence Honles

Bisakah saya menjadikan nama file sementara itu unik juga? jadi saya bisa menyimpannya nanti ketika subproses selesai dengan nama unik
MysticCodes

@Terence Honles: Saya menyarankan tempfile.NamedT TemporaryFile () pada awalnya, tetapi Anda tidak dapat menggunakannya untuk membuat file sementara yang dapat diakses oleh proses lain di Windows. NamedT TemporaryFile (delete = False) jelas lebih bersih . @ user343934: tempfile.mkstemp () dijamin memberi Anda nama unik setiap kali dipanggil - ini menghasilkan nama secara acak dan menggunakan fasilitas OS (O_EXCL, jika Anda bertanya-tanya) untuk menghindari benturan.
Richard Barrell

wow saya tidak tahu itu tidak berfungsi di windows ... gagal :( ... Saya rasa itu bagus untuk diketahui
Terence Honles

@Terence Honles: NamedT TemporaryFile () sebenarnya tidak gagal di Windows (sejauh yang saya tahu), tetapi Anda tidak dapat menutup file tanpa menghapusnya juga, dan (seperti yang saya pahami semantik file di Windows) tidak ada program lain yang dapat membuka file saat Anda membukanya. Saya mungkin salah; semantik untuk memiliki beberapa proses berbagi file di bawah Windows mungkin telah berubah sejak saya terakhir memeriksanya.
Richard Barrell

33

The uuidmodul akan menjadi pilihan yang baik, saya lebih suka menggunakan uuid.uuid4().hexsebagai nama file acak karena akan kembali sebuah string hex tanpa strip .

import uuid
filename = uuid.uuid4().hex

Outputnya akan seperti ini:

>>> import uuid
>>> uuid.uuid()
UUID('20818854-3564-415c-9edc-9262fbb54c82')
>>> str(uuid.uuid4())
'f705a69a-8e98-442b-bd2e-9de010132dc4'
>>> uuid.uuid4().hex
'5ad02dfb08a04d889e3aa9545985e304'  # <-- this one

1
Apa masalah memiliki tanda hubung?
David Lopez

15

Mungkin Anda membutuhkan file sementara yang unik?

import tempfile

f = tempfile.NamedTemporaryFile(mode='w+b', delete=False)

print f.name
f.close()

f membuka file. delete=FalseBerarti jangan hapus file setelah ditutup.

Jika Anda membutuhkan kontrol atas nama file, ada opsional prefix=...dan suffix=...argumen yang mengambil string. Lihat https://docs.python.org/3/library/tempfile.html .


Ini bagus jika Anda tidak perlu mengontrol nama file.
hiwaylon

1
Ini harus menjadi tmpfile.NamedT TemporaryFile bukan hanya NamedT TemporaryFile.
pengguna1993015

w+badalah defaultnya mode. Menggunakan tempfilefungsionalitas apa pun memiliki kerugian berupa izin akses file yang salah: tempfiledokumen digunakan os.O_TMPFILEsebagai masker, tetapi pembuatan file normal menghormati os.umask().
m8mble

8

Anda dapat menggunakan modul datetime

import datetime
uniq_filename = str(datetime.datetime.now().date()) + '_' + str(datetime.datetime.now().time()).replace(':', '.')

Perhatikan bahwa: Saya menggunakan replacekarena titik dua tidak diperbolehkan dalam nama file di banyak sistem operasi.

Itu saja, ini akan memberi Anda nama file unik setiap saat.


2
Kecuali jika nama file dibuat segera setelah satu sama lain (misalnya dalam satu lingkaran). Maka mereka sama.
skjerns

1

Saya menemukan pertanyaan ini, dan saya akan menambahkan solusi saya untuk mereka yang mungkin mencari sesuatu yang serupa. Pendekatan saya hanya membuat nama file acak dari asciikarakter. Ini akan menjadi unik dengan probabilitas yang baik.

from random import sample
from string import digits, ascii_uppercase, ascii_lowercase
from tempfile import gettempdir
from os import path

def rand_fname(suffix, length=8):
    chars = ascii_lowercase + ascii_uppercase + digits

    fname = path.join(gettempdir(), 'tmp-'
                + ''.join(sample(chars, length)) + suffix)

    return fname if not path.exists(fname) \
                else rand_fname(suffix, length)

1
Jawaban yang jelas untuk pertanyaan itu berkaitan dengan paket uuid. Namun server target saya memiliki python 2.4, tidak ada paket uuid dan peningkatan tidak diizinkan oleh pemilik server karena inkompatibilitas perangkat lunak lama, jadi jawaban ini berfungsi untuk saya.
Alberto Gaona

1
Saya sangat menyukai jawaban ini: dapat dengan mudah disesuaikan dengan spesifikasi proyek.
swdev

1
1) Tidak ada alasan untuk menggunakan rekursi di sini, terutama tanpa batas. 2) Terdapat kondisi balapan antara waktu path.exists()pengembalian Falsedan waktu konsumen benar-benar membuka file.
Jonathon Reinhart

1

Ini bisa dilakukan dengan menggunakan fungsi unik di modul ufp.path .

import ufp.path
ufp.path.unique('./test.ext')

jika jalur saat ini ada file 'test.ext'. ufp.path.unique function return './test (d1) .ext'.


6
ufp adalah bagian dari drupal? bukan modul standar
endolith

1

Untuk membuat jalur file unik jika ada, gunakan paket acak untuk membuat nama string baru untuk file. Anda dapat merujuk kode di bawah ini untuk hal yang sama.

import os
import random
import string

def getUniquePath(folder, filename):    
    path = os.path.join(folder, filename)
    while os.path.exists(path):
         path = path.split('.')[0] + ''.join(random.choice(string.ascii_lowercase) for i in range(10)) + '.' + path.split('.')[1]
    return path

Sekarang Anda dapat menggunakan jalur ini untuk membuat file yang sesuai.


1

Jika Anda memerlukan ID unik pendek sebagai nama file Anda, coba shortuuid, shortuuid menggunakan huruf kecil dan besar serta angka, dan hapus karakter yang tampak serupa seperti l, 1, I, O dan 0.

>>> import shortuuid
>>> shortuuid.uuid()
'Tw8VgM47kSS5iX2m8NExNa'
>>> len(ui)
22

dibandingkan dengan

>>> import uuid
>>> unique_filename = str(uuid.uuid4())
>>> len(unique_filename)
36
>>> unique_filename
'2d303ad1-79a1-4c1a-81f3-beea761b5fdf'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.