os.path.makedirs(name, mode=mode, os.path.exists(name))
Salut,
Ce sujet est un "rat hole" (trou à rat) ou un "catch-22" (attrape mouches).
Car si le "fonctionnel" est à la base relativement simple, le "contexte" de son application en fait un fourre-tout.
Le sujet pourrait se résumer à la définition d'une fonction nommée: "create_dir_if_not_exists".
C'est un "rat hole" car un répertoire est un objet persistant. Vivant sa vie après l'exécution du programme, il aura les propriétés attendues juste après sa création. Lorsqu'il existe déjà (et c'est le cas "normal"), il faudra en "pré-requis", s'assurer de son état avant d'imaginer pouvoir penser à s'en servir.
La liste des pré-requis devant être adaptée à un contexte, ce sera toujours trop ou pas assez.
A minima, c'est une "variation" sur mkdir, pourquoi ne pas oser:
Code:
1 2 3 4 5
| import os
def my_mkdir(name):
if not os.path.exists(name):
os.mkdir(name)
assert os.path.isdir(name)) |
La création conditionnelle du répertoire est réalisée "à la lettre".
Dans tous les cas, on s'assure que le pré-requis "est un répertoire" est "satisfait". Charge à l'appelant de se débrouiller avec les éventuelles exceptions.
Note: remonter ou pas des erreurs "précises" dépendra de la capacité de l'appelant à les gérer... ou de la nécessité d'afficher des messages "clairs" à la place de la seule trace de l'exception (exigences louables côté maintenabilité, support des utilisateurs mais décalées par rapport au fonctionnel au "business" d'un create if not exists).
Cela ne traite pas le cas où plusieurs instances de l'application pourraient créer le répertoire en même temps.
Mais dans ce cas, est-il raisonnable d'essayer de créer le répertoire? L'utilisateur pouvant ne pas avoir les bons droits pour le créer "proprement", il sera souvent préférable de s'en remettre à l'administrateur système. Dans ce cas, os.path.is_dir(name) pourrait être largement suffisant. Mais ici c'est pour le fun du passage d'une suite d'instruction en séquence à un try/catch.
Traiter cette exigence passe par attraper les exceptions retournées par mkdir et filtrer (ne pas remonter) celles correspondant à ce cas là.
Pour les autres, c'est toujours le problème de l'appelant!!!
Code:
1 2 3 4 5 6 7 8 9 10
| import os
import errno
def my_mkdir(name):
if not os.path.exists(name):
try:
os.mkdir(name)
except OSError as e:
if e.errno != errno.EEXIST:
raise
assert os.path.isdir(name)) |
A la relecture, on pourra "simplifier" le code (moins de lignes) en regardant ce qui tombe du mkdir plutôt que de se poser des questions avant et après...
Code:
1 2 3 4 5 6 7 8
| import os
import errno
def my_mkdir(name):
try:
os.mkdir(name)
except OSError as e:
if not (e.errno == errno.EEXIST and os.path.isdir(name)):
raise |
De fait, c'est moins lisible! Il faudra certainement remplacer le code retiré par des commentaires.
Python 3.2 a ajouté le paramètre exist_ok à la fonction os.makedirs qui permet d'en faire plus avec encore moins de lignes:
Code:
1 2 3
| import os
def my_mkdir(name, mode=0o777):
os.path.makedirs(name, mode, os.path.exists(name)) |
Encore plus opaque, mais plus besoin de documenter!
Cordialement,
- W