"Open()" de Python jette différentes erreurs pour "Fichier introuvable" - comment gérer les deux exceptions?
J'ai un scénario où l'utilisateur est invité à saisir un nom de fichier (un fichier est ouvert), et si le fichier n'existe pas dans le répertoire courant, 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 en Python 3.3 x, cela fonctionnait parfaitement lorsque je tapais le mauvais nom de fichier exprès (il exécute la suite sous"expect").
Cependant, quand je voulais exécuter mon code sur un ordinateur Windows en Python 3.2 x, je reçois une erreur qui dit que "FileNotFoundError" n'est pas défini. Ainsi, Python 3.2 sur Windows pense que "FileNotFoundError" est une variable et les programmes se ferme avec une erreur.
J'ai compris que Python 3.2 sur Windows lance un "IOError" si le nom de fichier d'entrée n'est pas valide. Je l'ai testé sur ma machine Linux en python 2.7, et c'est aussi une erreur IOError.
Mon problème est maintenant, que le code avec
except "FileNotFoundError":
Ne fonctionnera pas sur Python 3.2 de Windows, mais si je le change en
except "IOError":
Ça ne marchera pas sur mon Mac plus.
Comment pourrais-je contourner cela? La seule façon dont je peux penser est d'utiliser juste
except
, ce que je ne veux généralement pas.
4 réponses
Dans 3.3, IOError
est devenu un alias pour OSError
, et FileNotFoundError
est une sous-classe de OSError
. Donc, vous pouvez essayer
except (OSError, IOError) as e:
...
Cela va lancer un réseau assez large, et vous ne pouvez pas supposer que l'exception est "file not found" sans inspecter e.errno
, mais cela peut couvrir votre cas d'utilisation.
PEP 3151 discute en détail de la justification du changement.
Cela me semble mieux qu'un simple except:
, mais je ne suis pas sûr si c'est la meilleure solution:
error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError)
try:
f = open('.....')
except error_to_catch:
print('!')
Donc, pour attraper exactement seulement quand 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 ne savais pas que c'est ce que vous demandiez. J'espère qu'il y a 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 ce conditionnel avec plus d'éloquence dans sa réponse
(error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))