La mejor manera de generar nombres de archivos aleatorios en Python

En Python, ¿cuál es una buena o la mejor manera de generar un texto aleatorio para anteponer a un archivo (nombre) que estoy guardando en un servidor, solo para asegurarse de que no se sobrescriba? ¡Gracias!

Python tiene facilidades para generar nombres de archivos temporales, consulte http://docs.python.org/library/tempfile.html . Por ejemplo:

In [4]: import tempfile 

Cada llamada a tempfile.NamedTemporaryFile() da como resultado un archivo temporal diferente, y se puede acceder a su nombre con el atributo .name , por ejemplo:

 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 vez que tenga el nombre de archivo único, se puede utilizar como cualquier archivo normal. Nota : de forma predeterminada, el archivo se eliminará cuando se cierre. Sin embargo, si el parámetro de delete es False, el archivo no se elimina automáticamente.

Conjunto de parámetros completo:

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

también es posible especificar el prefijo para el archivo temporal (como uno de los diversos parámetros que se pueden suministrar durante la creación del archivo):

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

Puede encontrar ejemplos adicionales para trabajar con archivos temporales aquí.

Podría usar el módulo UUID para generar una cadena aleatoria:

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

Esta es una opción válida, dado que es muy poco probable que un generador UUID produzca un identificador duplicado (un nombre de archivo, en este caso):

Solo después de generar 1 mil millones de UUID por segundo durante los próximos 100 años, la probabilidad de crear un solo duplicado sería aproximadamente del 50%. La probabilidad de un duplicado sería aproximadamente del 50% si cada persona en la tierra posee 600 millones de UUID.

un enfoque común es agregar una marca de tiempo como prefijo / sufijo al nombre de archivo para tener alguna relación temporal con el archivo. Si necesita más exclusividad, aún puede agregar una cadena aleatoria a esto.

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

El OP solicitó crear nombres de archivos aleatorios, no archivos aleatorios. Los tiempos y los UUID pueden chocar. Si está trabajando en una sola máquina (no es un sistema de archivos compartido) y su proceso / subproceso no pisará el control de sí mismo, use os.getpid () para obtener su propio PID y utilícelo como un elemento de un nombre de archivo único. Otros procesos obviamente no obtendrían el mismo PID. Si eres multihilo, obtén el ID del hilo. Si tiene otros aspectos de su código en los que un solo hilo o proceso podría generar múltiples archivos temporales diferentes, es posible que necesite utilizar otra técnica. Un índice móvil puede funcionar (si no los mantiene por tanto tiempo o no utiliza tantos archivos, podría preocuparse por la transferencia). Mantener un hash / índice global en archivos “activos” sería suficiente en ese caso.

Lo siento por la larga explicación, pero depende de su uso exacto.

Si desea conservar el nombre del archivo original como parte del nuevo nombre de archivo, los prefijos únicos de longitud unifom pueden ser generados por:

 def add_prefix(filename): from hashlib import md5 from time import localtime return "%s_%s" % (md5(str(localtime())).hexdigest(), filename) 

Las llamadas a àdd_prefix (‘style.css’) generan una secuencia como:

 a38ff35794ae366e442a0606e67035ba_style.css 7a5f8289323b0ebfdbc7c840ad3cb67b_style.css 

Si no necesita la ruta del archivo, pero solo la cadena aleatoria tiene una longitud predefinida, puede usar algo como esto.

 import random import string file_name = ''.join([random.choice(string.ascii_lowercase) for i in range(16)]) 

Agregando mis dos centavos aquí:

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

De acuerdo con el documento de python para tempfile.mkstemp, crea un archivo temporal de la manera más segura posible. Tenga en cuenta que el archivo existirá después de esta llamada:

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

Personalmente, prefiero que mi texto no solo sea aleatorio / único, sino también bello, por eso me gusta el hashids lib, que genera un texto aleatorio de enteros que se ve bien. Se puede instalar a través de

pip install hashids

Retazo:

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

Breve descripción:

Hashids es una pequeña biblioteca de código abierto que genera identificadores cortos, únicos y no secuenciales a partir de números.

Podrías usar el paquete al azar:

 import random file = random.random()