Vérifier si un répertoire existe et le créer si nécessaire ?
La réponse directe à cette question est, en supposant une situation simple où vous ne vous attendez pas à ce que d'autres utilisateurs ou processus s'immiscent dans votre répertoire :
if not os.path.exists(d):
os.makedirs(d)
ou si la création du répertoire est sujette à des conditions de course (c'est-à-dire si après avoir vérifié que le chemin existe, quelque chose d'autre peut l'avoir déjà créé), faites ceci :
import errno
try:
os.makedirs(d)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
Mais une meilleure approche consiste peut-être à contourner le problème de contention des ressources en utilisant des répertoires temporaires par le biais de tempfile
:
import tempfile
d = tempfile.mkdtemp()
Voici l'essentiel du document en ligne :
mkdtemp(suffix='', prefix='tmp', dir=None)
User-callable function to create and return a unique temporary
directory. The return value is the pathname of the directory.
The directory is readable, writable, and searchable only by the
creating user.
Caller is responsible for deleting the directory when done with it.
Nouveau dans Python 3.5 : pathlib.Path
avec exist_ok
Il y a un nouveau Path
(à partir de la version 3.4) avec de nombreuses méthodes que l'on peut utiliser avec les chemins - l'une d'entre elles est la suivante mkdir
.
(Pour le contexte, je suis mon rep hebdomadaire avec un script. Voici les parties pertinentes du code du script qui me permettent d'éviter de frapper Stack Overflow plus d'une fois par jour pour les mêmes données).
Tout d'abord, les importations concernées :
from pathlib import Path
import tempfile
Nous n'avons pas à faire face à os.path.join
maintenant - il suffit de joindre les parties du chemin avec un /
:
directory = Path(tempfile.gettempdir()) / 'sodata'
Ensuite, je m'assure de manière idempotente que le répertoire existe - la fonction exist_ok
apparaît dans Python 3.5 :
directory.mkdir(exist_ok=True)
Voici la partie pertinente de l'article documentation :
Si exist_ok
est vrai, FileExistsError
les exceptions seront ignorées (même comportement que l'option POSIX mkdir -p
), mais seulement si le dernier composant du chemin d'accès n'est pas un fichier non répertorié existant.
Voici un peu plus du script - dans mon cas, je ne suis pas soumis à une condition de course, je n'ai qu'un seul processus qui s'attend à ce que le répertoire (ou les fichiers contenus) soit là, et je n'ai rien qui essaie de supprimer le répertoire.
todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
logger.info("todays_file exists: " + str(todays_file))
df = pd.read_json(str(todays_file))
Path
les objets doivent être contraints à str
avant les autres API qui attendent str
les chemins peuvent les utiliser.
Peut-être que Pandas devrait être mis à jour pour accepter les instances de la classe de base abstraite, os.PathLike
.
40 votes
En général, vous devrez tenir compte du cas où le nom du fichier ne contient pas de répertoire. Sur ma machine, dirname('foo.txt') donne '', qui n'existe pas et fait échouer makedirs().
14 votes
Dans python 2.7
os.path.mkdir
n'existe pas. C'estos.mkdir
.9 votes
Si le chemin existe il faut non seulement vérifier si c'est un répertoire et non un fichier normal ou un autre objet (beaucoup de réponses vérifient cela) mais il faut aussi vérifier s'il est accessible en écriture (je n'ai pas trouvé de réponse qui vérifie cela).
13 votes
Dans le cas où vous êtes venu ici pour créer des répertoires parents de la chaîne de chemin de fichier
p
Voici mon extrait de code :os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
2 votes
méta-discussion des réponses à cette question
1 votes
En ce qui concerne les conditions de course pour le cas où le disque est presque plein, vous pouvez éventuellement vérifier qu'un seuil minimum (défini par l'utilisateur) d'espace libre existe avant d'essayer de le faire : Espace restant sur le volume sur plusieurs plates-formes à l'aide de python