168 votes

Meilleur moyen de générer des noms de fichiers aléatoires en Python

En Python, quelle est la meilleure façon de générer un texte aléatoire à ajouter au début d'un fichier (nom) que j'enregistre sur un serveur, juste pour s'assurer qu'il n'est pas écrasé. Merci !

202voto

Óscar López Points 97105

Vous pourriez utiliser le Module UUID pour générer une chaîne aléatoire :

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

Il s'agit d'un choix valable, étant donné qu'une UUID est extrêmement peu susceptible de produire un identifiant en double (un nom de fichier, dans ce cas) :

Seulement après avoir généré 1 milliard d'UUID chaque seconde pendant les 100 prochaines années, la probabilité de créer un seul doublon serait d'environ 50 %. La probabilité de créer un seul double serait d'environ 50% si chaque personne sur terre possède 600 millions d'UUIDs.

23 votes

Cette fonction est également très utile lorsque vous voulez un nom de fichier unique, mais que vous ne voulez pas encore le créer.

26 votes

Ou utilisez uuid.uuid4().hex pour obtenir une chaîne hexagonale sans tirets ( - ).

158voto

Levon Points 34085

Python permet de générer des noms de fichiers temporaires, cf. http://docs.python.org/library/tempfile.html . Par exemple :

In [4]: import tempfile

Chaque appel à tempfile.NamedTemporaryFile() donne lieu à un fichier temporaire différent, et son nom peut être consulté avec la commande .name attribut, par exemple :

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'

Une fois que vous avez le nom de fichier unique, il peut être utilisé comme n'importe quel fichier ordinaire. Note : Par défaut, le fichier sera supprimé lorsqu'il est fermé. Toutefois, si le delete paramètre est False, le fichier n'est pas automatiquement supprimé.

Jeu de paramètres complet :

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

il est également possible de spécifier le préfixe du fichier temporaire (parmi les différents paramètres qui peuvent être fournis lors de la création du fichier) :

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

Des exemples supplémentaires pour travailler avec les fichiers temporaires peuvent être trouvés aquí

1 votes

Ces fichiers seront-ils supprimés au prochain redémarrage de ma machine ?

33 votes

Le problème de cette solution est qu'elle génère non seulement un nom de fichier, mais aussi un fichier déjà ouvert. Si vous avez besoin d'un nom de fichier temporaire pour un nouveau fichier qui n'existe pas encore (par exemple, pour l'utiliser comme sortie d'une commande os), cela ne conviendra pas. Dans ce cas, vous pouvez faire quelque chose comme str(uuid.uuid4()) .

0 votes

@Luca Merci pour le commentaire supplémentaire, c'est utile, et noté pour référence future. Cependant, l'OP a clairement indiqué qu'il/elle voulait enregistrer un fichier, d'où la nécessité de l'ouvrir, donc cette solution y pourvoit.

30voto

moooeeeep Points 10167

Une approche courante consiste à ajouter un horodatage en tant que préfixe/suffixe au nom du fichier afin d'avoir une certaine relation temporelle avec le fichier. Si vous avez besoin de plus d'unicité, vous pouvez toujours ajouter une chaîne aléatoire à ce nom.

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 votes

Dans un environnement multithread, il est possible qu'une condition de course soit impliquée dans la séquence suivante 1. Test if file exists, 2. create file. Si un autre processus interrompt le vôtre entre les étapes 1 et 2, et crée le fichier, lorsque votre code reprend, il écrasera le fichier de l'autre processus.

0 votes

@Li-aungYip En outre, vous pouvez également utiliser 6-8 séquence de caractères aléatoires (dans le cas où 2 fichiers sont générés dans la même seconde).

0 votes

@bobobo : Ou vous pourriez utiliser le tempfile qui s'en occupe pour vous :)

14voto

Brad Points 6004

L'OP a demandé de créer des noms de fichiers pas aléatoire fichiers . Les temps et les UUIDs peuvent entrer en collision. Si vous travaillez sur une seule machine (pas sur un système de fichiers partagé) et que votre processus/thread ne se piétine pas lui-même, utilisez os.getpid() pour obtenir votre propre PID et utilisez-le comme élément d'un nom de fichier unique. Les autres processus n'obtiendront évidemment pas le même PID. Si vous êtes multithreadé, obtenez l'identifiant du thread. Si vous avez d'autres aspects de votre code dans lesquels un seul thread ou processus pourrait générer plusieurs tempfiles différents, vous devrez peut-être utiliser une autre technique. Un index roulant peut fonctionner (si vous ne les conservez pas si longtemps ou si vous n'utilisez pas tant de fichiers que vous vous inquiéteriez du roulement). Dans ce cas, il suffit de conserver un hachage/index global des fichiers "actifs".

Désolé pour cette longue explication, mais cela dépend de votre utilisation exacte.

14voto

fenix Points 115

Si vous n'avez pas besoin du chemin d'accès au fichier, mais seulement d'une chaîne aléatoire de longueur prédéfinie, vous pouvez utiliser quelque chose comme ceci.

>>> import random
>>> import string

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X