Python: ¿Cómo crear un nombre de archivo único?

8 minutos de lectura

avatar de usuario
códigos místicos

Tengo un formulario web de Python con dos opciones: Subir archivo y área de texto. Necesito tomar los valores de cada uno y pasarlos a otro programa de línea de comandos. Puedo pasar fácilmente el nombre del archivo con las opciones de carga de archivos, pero no estoy seguro de cómo pasar el valor del área de texto.

Creo que lo que tengo que hacer es:

  1. Generar un nombre de archivo único
  2. Cree un archivo temporal con ese nombre en el directorio de trabajo
  3. Guarde los valores pasados ​​​​de textarea en el archivo temporal
  4. Ejecute el programa de línea de comandos desde dentro de mi módulo de python y pásele el nombre del archivo temporal

No estoy seguro de cómo generar un nombre de archivo único. ¿Alguien puede darme algunos consejos sobre cómo generar un nombre de archivo único? Se agradece cualquier algoritmo, sugerencia y línea de código.

Gracias por tu preocupación

  • Edité tu pregunta para tratar de hacerla más clara. ¡Avísame si interpreté algo incorrectamente!

    – culix

    1 de septiembre de 2012 a las 10:12

avatar de usuario
EnigmaCurry

No pensé que su pregunta fuera muy clara, pero si todo lo que necesita es un nombre de archivo único…

import uuid

unique_filename = str(uuid.uuid4())

  • Lo siento, estoy trabajando en la plataforma de Windows, así que no sé cómo manejar el subproceso

    – Códigos místicos

    3 de junio de 2010 a las 10:04

  • uuid parece crear una cadena larga y única. No creo que sea mejor tener un nombre de archivo con una cadena larga y UUID, () en él.

    – Códigos Místicos

    3 de junio de 2010 a las 10:37

  • pienso uuid.uuid4().hex sería una mejor opción, ver detalle aquí.

    – Gris Li

    9 de julio de 2017 a las 1:55


  • @ToloPalmer: es más probable que la CPU de su computadora tenga un error de procesamiento que haga que cargue el archivo incorrecto que un UUID generado que colisione con cualquier valor existente. UUID produce un nombre único en un modelo de computación que entiende que no toda la computación es matemática pura.

    – GManNickG

    9 de julio de 2017 a las 2:05

  • Disculpe mi ignorancia, viejo comentario… De hecho, no es único, pero es muy poco probable que colisione, así que es una buena elección;)

    –Tolo Palmer

    9 de julio de 2017 a las 9:25

avatar de usuario
ricardo barrel

Si desea crear archivos temporales en Python, hay un módulo llamado archivo temporal en las bibliotecas estándar de Python. Si desea iniciar otros programas para operar en el archivo, use tempfile.mkstemp() para crear archivos y os.fdopen() para acceder a los descriptores de archivo que le proporciona mkstemp().

Por cierto, ¿dices que estás ejecutando comandos desde un programa de Python? Es casi seguro que debería estar usando el subproceso módulo.

Así que puedes escribir alegremente un código que se parece a:

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)

Ejecutando eso, deberías encontrar que el cat El comando funcionó perfectamente bien, pero el archivo temporal se eliminó en el finally bloquear. Sea consciente de que usted tener para eliminar el archivo temporal que mkstemp() devuelve usted mismo: ¡la biblioteca no tiene forma de saber cuándo ha terminado con él!

(Editar: supuse que NamedTemporaryFile hizo exactamente lo que buscaba, pero eso podría no ser tan conveniente: el archivo se elimina inmediatamente cuando se cierra el objeto del archivo temporal y otros procesos abren el archivo antes de cerrarlo no funcionará en algunas plataformas, especialmente en Windows. Lo siento, fallé de mi parte).

  • usando NamedTemporaryFile es probablemente lo que quieren (a menos que quieran que permanezca en el servidor, y luego pueden usar “tempfile.NamedTemporaryFile(delete=False)”)

    – Terence Honles

    2 de junio de 2010 a las 21:24

  • ¿Puedo hacer que ese nombre de archivo temporal también sea único? para poder guardarlo más tarde cuando el subproceso se complete con un nombre único

    – Códigos Místicos

    2 de junio de 2010 a las 21:25

  • @Terence Honles: Originalmente sugerí tempfile.NamedTemporaryFile(), pero realmente no puede usarlo para crear archivos temporales a los que otros procesos pueden acceder en Windows. NamedTemporaryFile(delete=False) ciertamente lo es limpiador, aunque. @user343934: se garantiza que tempfile.mkstemp() le dará un nombre único cada vez que se llame; genera los nombres aleatoriamente y usa las instalaciones del sistema operativo (O_EXCL, si se lo pregunta) para evitar colisiones.

    – Richard Barrell

    2 de junio de 2010 a las 21:33


  • wow, no sabía que no funciona en Windows… falla 🙁 …supongo que es bueno saberlo

    – Terence Honles

    4 de junio de 2010 a las 6:30

  • @Terence Honles: NamedTemporaryFile() en realidad no falla en Windows (que yo sepa), pero no puede cerrar el archivo sin eliminarlo también y (según tengo entendido la semántica de archivos en Windows) ningún otro programa puede abrir el archivo mientras lo tiene abierto. Podría estar equivocado; la semántica para tener múltiples procesos compartiendo un archivo en Windows podría haber cambiado desde la última vez que lo verifiqué.

    – Richard Barrell

    4 de junio de 2010 a las 11:43

avatar de usuario
Li gris

los uuid módulo sería una buena opción, prefiero usar uuid.uuid4().hex como nombre de archivo aleatorio porque devolverá una cadena hexadecimal sin guiones.

import uuid
filename = uuid.uuid4().hex

Las salidas deberían ser así:

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

  • ¿Cuál es el problema de tener guiones?

    –David López

    25 de marzo de 2020 a las 20:39

  • ¿Es estética o hay otra razón para agregar .hex?

    – simanacci

    6 de febrero de 2021 a las 8:07

  • Normalmente usaría los guiones para separar palabras en un nombre de archivo (p. ej. my-favorite-shoes.jpg). Sin embargo, si el nombre de archivo se genera aleatoriamente, preferiría un nombre de archivo sin guiones, es más hermoso y los guiones aquí no tienen sentido.

    – Gris Li

    7 de febrero de 2021 a las 6:04

avatar de usuario
Роман Буртник

¿Quizás necesite un archivo temporal único?

import tempfile

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

print f.name
f.close()

f es un archivo abierto. delete=False significa no eliminar el archivo después de cerrarlo.

Si necesita controlar el nombre del archivo, hay opciones prefix=... y suffix=... argumentos que toman cadenas. Ver https://docs.python.org/3/library/tempfile.html.

avatar de usuario
Nimish Agrawal

Puedes usar el fecha y hora módulo

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

Tenga en cuenta que: estoy usando replace ya que los dos puntos no están permitidos en los nombres de archivo en muchos sistemas operativos.

Eso es todo, esto le dará un nombre de archivo único cada vez.

  • A menos que los nombres de archivo se creen inmediatamente después de otro (por ejemplo, en un bucle). Entonces son iguales.

    – Skjerns

    19 de noviembre de 2018 a las 12:48


avatar de usuario
milind deore

En caso de que necesite identificaciones cortas únicas como su nombre de archivo, intente shortuuid, corto utiliza letras y dígitos en mayúsculas y minúsculas, y elimina caracteres de aspecto similar como l, 1, I, O y 0.

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

comparado con

>>> import uuid
>>> unique_filename = str(uuid.uuid4())
>>> len(unique_filename)
36
>>> unique_filename
'2d303ad1-79a1-4c1a-81f3-beea761b5fdf'

  • A menos que los nombres de archivo se creen inmediatamente después de otro (por ejemplo, en un bucle). Entonces son iguales.

    – Skjerns

    19 de noviembre de 2018 a las 12:48


Encontré esta pregunta y agregaré mi solución para aquellos que puedan estar buscando algo similar. Mi enfoque fue solo hacer un nombre de archivo aleatorio a partir de ascii caracteres. Será único con una buena probabilidad.

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)

  • La respuesta obvia a la pregunta tenía que ver con el paquete uuid. Sin embargo, mi servidor de destino tiene python 2.4, no tiene un paquete uuid y el propietario del servidor no autorizó la actualización debido a incompatibilidades de software heredadas, por lo que esta respuesta funciona para mí.

    –Alberto Gaona

    3 oct 2014 a las 18:04

  • Me gusta especialmente esta respuesta: se puede ajustar fácilmente a las especificaciones del proyecto.

    – swdev

    29 de abril de 2015 a las 2:41

  • 1) No hay razón para usar la recursividad aquí, especialmente sin límites. 2) Existe condición de carrera entre el tiempo que path.exists() devoluciones False y la hora en que un consumidor realmente abre el archivo.

    – Jonathan Reinhart

    08/04/2017 a las 22:21

¿Ha sido útil esta solución?