J'ai un script où un utilisateur est invité à taper un nom de fichier (d'un fichier à ouvrir), et si le fichier n'existe pas dans le répertoire en cours, l'utilisateur est invité à nouveau. Voici la version courte:
file = input("Type filename: ")
...
try:
fileContent = open(filename, "r")
...
except FileNotFoundError:
...
Lorsque j'ai testé mon script sur mon MacOS X dans Python 3.3x), il fonctionnait parfaitement bien lorsque je tapais exprès le nom de fichier incorrect (la suite est exécutée sous "expect").
Cependant, lorsque je voulais exécuter mon code sur un ordinateur Windows sous Python 3.2x, je reçois une erreur indiquant que "FileNotFoundError" n'est pas défini. Donc, Python 3.2 sur Windows pense que "FileNotFoundError" est une variable et que le programme se ferme avec une erreur.
J'ai découvert que Python 3.2 sous Windows génère un "IOError" si le nom du fichier en entrée n'est pas valide. Je l'ai testé sur ma machine Linux sous Python 2.7, et c'est aussi un IOError.
Mon problème est maintenant, que le code avec
except "FileNotFoundError":
ne fonctionnera pas sous Windows Python 3.2, mais si je le change en
except "IOError":
ça ne marchera plus sur mon Mac.
Comment pourrais-je le contourner? Le seul moyen auquel je puisse penser est d'utiliser uniquement except
, ce que je ne veux généralement pas.
En 3.3, IOError
est devenu un alias pour OSError
, et FileNotFoundError
est une sous-classe de OSError
. Alors tu pourrais essayer
except (OSError, IOError) as e:
...
Cela va jeter un filet assez large, et vous ne pouvez pas supposer que l’exception est "fichier non trouvé" sans inspecter e.errno
, mais cela peut couvrir votre cas d'utilisation.
PEP 3151 explique en détail la raison du changement.
Cela me semble meilleur qu'un simple except:
, mais je ne suis pas sûr que ce soit la meilleure solution:
error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError)
try:
f = open('.....')
except error_to_catch:
print('!')
Donc, pour attraper exactement que lorsqu'un fichier n'est pas trouvé, je fais:
import errno
try:
open(filename, 'r')
except (OSError, IOError) as e: # FileNotFoundError does not exist on Python < 3.3
if getattr(e, 'errno', 0) == errno.ENOENT:
... # file not found
raise
vous pouvez attraper 2 erreurs en même temps
except (FileNotFoundError, IOError):
Je n'avais pas réalisé que c'était ce que vous demandiez. J'espère qu'il existe une solution plus éloquente que d'inspecter manuellement
try:
error_to_catch = FileNotFoundError
except NameError:
error_to_catch = IOError
except error_to_catch
cwallenpoole fait cela plus éloquemment dans sa réponse (error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))