En Python, quelle est la bonne ou la meilleure façon de générer du texte aléatoire à ajouter à un fichier (nom) que j'enregistre sur un serveur, juste pour m'assurer qu'il n'écrase pas. Je vous remercie!
Réponses:
Python a des fonctionnalités pour générer des noms de fichiers temporaires, voir http://docs.python.org/library/tempfile.html . Par exemple:
In [4]: import tempfile
Chaque appel à tempfile.NamedTemporaryFile()
entraîne un fichier temporaire différent, et son nom est accessible avec l' .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. Remarque : Par défaut, le fichier sera supprimé lors de sa fermeture. Cependant, 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 (comme l'un des différents paramètres pouvant ê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 des fichiers temporaires peuvent être trouvés ici
Vous pouvez utiliser le module UUID pour générer une chaîne aléatoire:
import uuid
filename = str(uuid.uuid4())
C'est un choix valable, étant donné qu'un générateur d' UUID est extrêmement peu susceptible de produire un identifiant en double (un nom de fichier, dans ce cas):
Ce n'est qu'après avoir généré 1 milliard d'UUID par seconde pendant les 100 prochaines années, que la probabilité de créer un seul duplicata serait d'environ 50%. La probabilité d'un duplicata serait d'environ 50% si chaque personne sur terre possède 600 millions d'UUID.
uuid.uuid4().hex
pour obtenir une chaîne hexadécimale sans tirets ( -
).
une approche courante consiste à ajouter un horodatage comme préfixe / suffixe au nom de fichier pour avoir une relation temporelle avec le fichier. Si vous avez besoin de plus d'unicité, vous pouvez toujours y ajouter une chaîne aléatoire.
import datetime
basename = "mylogfile"
suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
filename = "_".join([basename, suffix]) # e.g. 'mylogfile_120508_171442'
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.
tempfile
module, qui gère cela pour vous. :)
...strftime("%y%m%d_%H%M%S%f")
L'OP a demandé de créer des noms de fichiers aléatoires et non des fichiers aléatoires . Les heures et les UUID peuvent entrer en collision. Si vous travaillez sur une seule machine (pas un système de fichiers partagé) et que votre processus / thread ne se piétine pas, utilisez os.getpid () pour obtenir votre propre PID et utilisez-le comme élément d'un nom de fichier unique. D'autres processus n'obtiendraient évidemment pas le même PID. Si vous êtes multithread, obtenez l'ID du thread. Si vous avez d'autres aspects de votre code dans lesquels un seul thread ou processus peut générer plusieurs fichiers temporaires différents, vous devrez peut-être utiliser une autre technique. Un index tournant peut fonctionner (si vous ne les conservez pas si longtemps ou si vous n'utilisez pas autant de fichiers, vous vous soucieriez du rollover). Garder un hachage / index global sur les fichiers "actifs" suffirait dans ce cas.
Désolé pour l'explication de longue date, mais cela dépend de votre utilisation exacte.
Si vous n'avez pas besoin du chemin du fichier, mais uniquement de la chaîne aléatoire ayant une longueur prédéfinie, vous pouvez utiliser quelque chose comme ça.
>>> import random
>>> import string
>>> file_name = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
>>> file_name
'ytrvmyhkaxlfaugx'
Si vous souhaitez conserver le nom de fichier d'origine en tant que partie du nouveau nom de fichier, des préfixes uniques de longueur uniforme peuvent être générés en utilisant les hachages MD5 de l'heure actuelle:
from hashlib import md5
from time import localtime
def add_prefix(filename):
prefix = md5(str(localtime()).encode('utf-8')).hexdigest()
return f"{prefix}_{filename}"
Les appels à add_prefix ('style.css') génèrent une séquence comme:
a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css
Ajout de mes deux cents ici:
In [19]: tempfile.mkstemp('.png', 'bingo', '/tmp')[1]
Out[19]: '/tmp/bingoy6s3_k.png'
Selon la documentation python pour tempfile.mkstemp, il crée un fichier temporaire de la manière la plus sécurisée possible. Veuillez noter que le fichier existera après cet appel:
In [20]: os.path.exists(tempfile.mkstemp('.png', 'bingo', '/tmp')[1])
Out[20]: True
Personnellement, je préfère que mon texte ne soit pas seulement aléatoire / unique mais aussi beau, c'est pourquoi j'aime la librairie hashids, qui génère un beau texte aléatoire à partir d'entiers. Peut être installé via
pip install hashids
Fragment:
import hashids
hashids = hashids.Hashids(salt="this is my salt", )
print hashids.encode(1, 2, 3)
>>> laHquq
Brève description:
Hashids est une petite bibliothèque open-source qui génère des identifiants courts, uniques et non séquentiels à partir de nombres.
>>> import random
>>> import string
>>> alias = ''.join(random.choice(string.ascii_letters) for _ in range(16))
>>> alias
'WrVkPmjeSOgTmCRG'
Vous pouvez changer 'string.ascii_letters' en n'importe quel format de chaîne comme vous le souhaitez pour générer n'importe quel autre texte, par exemple mobile NO, ID ...
import uuid
imageName = '{}{:-%Y%m%d%H%M%S}.jpeg'.format(str(uuid.uuid4().hex), datetime.now())
Vous pouvez utiliser le package aléatoire:
import random
file = random.random()