Il modo migliore per generare nomi di file casuali in Python


95

In Python, qual è un buon, o il modo migliore per generare del testo casuale da anteporre a un file (nome) che sto salvando su un server, solo per assicurarmi che non venga sovrascritto. Grazie!

Risposte:


109

Python dispone di funzionalità per generare nomi di file temporanei, vedere http://docs.python.org/library/tempfile.html . Per esempio:

In [4]: import tempfile

Ogni chiamata a tempfile.NamedTemporaryFile()risulta in un diverso file temporaneo e il suo nome è accessibile con l' .nameattributo, ad esempio:

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'

Una volta ottenuto il nome file univoco, può essere utilizzato come qualsiasi file normale. Nota : per impostazione predefinita, il file verrà eliminato alla chiusura. Tuttavia, se il deleteparametro è False, il file non viene eliminato automaticamente.

Set completo di parametri:

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

è inoltre possibile specificare il prefisso per il file temporaneo (come uno dei vari parametri che possono essere forniti in fase di creazione del file):

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

Ulteriori esempi per lavorare con file temporanei possono essere trovati qui


1
Quei file verranno eliminati la prossima volta che riavvio la mia macchina?
HelloWorld

15
Il problema con questa soluzione è che genera non solo un nome file, ma anche un file già aperto. Se è necessario un nome file temporaneo per un file nuovo, non ancora esistente (ad esempio, da utilizzare come output di un comando os), questo non funzionerà. In tal caso, puoi fare qualcosa come str (uuid.uuid4 ()).
Luca

@Luca Grazie per il commento aggiuntivo, utile e segnalato per riferimento futuro. Tuttavia, OP ha dichiarato chiaramente che voleva salvare un file, quindi è necessario aprirlo, quindi questa soluzione lo prevede.
Levon

Dipende. Forse ha bisogno del nome per costruire una chiamata al server appropriata. Non sono sicuro. In ogni caso la tua risposta è sicuramente il caso più comune.
Luca

105

È possibile utilizzare il modulo UUID per generare una stringa casuale:

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

Questa è una scelta valida, dato che è estremamente improbabile che un generatore di UUID produca un identificatore duplicato (un nome di file, in questo caso):

Solo dopo aver generato 1 miliardo di UUID al secondo per i prossimi 100 anni, la probabilità di creare un solo duplicato sarebbe di circa il 50%. La probabilità di un duplicato sarebbe di circa il 50% se ogni persona sulla terra possedesse 600 milioni di UUID.


16
questo è anche molto utile quando vuoi un nome di file univoco, ma non vuoi che sia ancora creato.
Prof. Falken

14
Oppure utilizzare uuid.uuid4().hexper ottenere una stringa esadecimale senza trattini ( -).
Rockallite

17

un approccio comune consiste nell'aggiungere un timestamp come prefisso / suffisso al nome del file per avere una relazione temporale con il file. Se hai bisogno di maggiore unicità, puoi comunque aggiungere una stringa casuale a questo.

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
In un ambiente multi-thread, c'è una possibile condizione di competizione coinvolta nella sequenza 1. Test if file exists, 2. create file.Se un altro processo interrompe il tuo tra i passaggi 1 e 2 e crea il file, quando il tuo codice riprende, sovrascriverà il file dell'altro processo.
Li-aung Yip

@ Li-aungYip Inoltre può anche utilizzare 6-8 sequenze di caratteri casuali (nel caso in cui 2 file vengono generati nello stesso secondo).
bobobobo

@bobobobo: Oppure potresti usare il tempfilemodulo, che gestisce questo per te. :)
Li-aung Yip

Suggerirei di aggiungere microsecondi, ad esempio...strftime("%y%m%d_%H%M%S%f")
AstraSerg

8

L'OP ha richiesto di creare nomi di file casuali non file casuali . I tempi e gli UUID possono entrare in conflitto. Se stai lavorando su una singola macchina (non un filesystem condiviso) e il tuo processo / thread non calpesterà se stessok, usa os.getpid () per ottenere il tuo PID e usalo come elemento di un nome di file univoco. Ovviamente altri processi non otterrebbero lo stesso PID. Se sei multithread, ottieni l'id del thread. Se si hanno altri aspetti del codice in cui un singolo thread o processo può generare più file temporanei diversi, potrebbe essere necessario utilizzare un'altra tecnica. Un indice a rotazione può funzionare (se non li conservi così a lungo o utilizzi così tanti file ti preoccupi del rollover). In questo caso sarebbe sufficiente mantenere un hash / indice globale sui file "attivi".

Mi dispiace tanto per la spiegazione prolissa, ma dipende dal tuo utilizzo esatto.


8

Se non hai bisogno del percorso del file, ma solo della stringa casuale di lunghezza predefinita puoi usare qualcosa di simile.

>>> import random
>>> import string

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

7

Se si desidera conservare il nome file originale come parte del nuovo nome file, è possibile generare prefissi univoci di lunghezza uniforme utilizzando gli hash MD5 dell'ora corrente:

from hashlib import md5
from time import localtime

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

Le chiamate a add_prefix ('style.css') generano una sequenza come:

a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css

1
Per evitare: gli oggetti Unicode devono essere codificati prima dell'hashing Ho cambiato in md5 (str (localtime ()). Encode ('utf-8')). Hexdigest ()
PhoebeB

1
Si noti che un hash di qualsiasi tipo di dati (incluso un timestamp) non garantisce l'unicità di per sé (non più di quanto non faccia una sequenza di byte scelta casualmente).
Peter O.

1

Aggiungendo i miei due centesimi qui:

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

Secondo il documento python per tempfile.mkstemp, crea un file temporaneo nel modo più sicuro possibile. Tieni presente che il file esisterà dopo questa chiamata:

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

1

Personalmente preferisco che il mio testo non sia solo casuale / unico ma anche bello, ecco perché mi piace hashid lib, che genera un testo casuale dall'aspetto piacevole da numeri interi. Può essere installato tramite

pip install hashids

Frammento:

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

Breve descrizione:

Hashids è una piccola libreria open source che genera ID brevi, univoci e non sequenziali dai numeri.


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

Puoi cambiare 'string.ascii_letters' in qualsiasi formato di stringa come preferisci per generare qualsiasi altro testo, ad esempio mobile NO, ID ... inserisci qui la descrizione dell'immagine


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

1
Sebbene questo codice possa risolvere la domanda, inclusa una spiegazione di come e perché questo risolve il problema aiuterebbe davvero a migliorare la qualità del tuo post e probabilmente si tradurrebbe in più voti positivi. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo alla persona che chiede ora. Si prega di modificare la risposta per aggiungere spiegazioni e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni.
Богдан Опир

-1

Potresti usare il pacchetto casuale:

import random
file = random.random()

file = str (random.random ())
anajem

Questo sta generando numeri casuali, non un testo casuale.
user1767754
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.