"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.

38
demandé sur Russell Borogove 2013-02-22 23:48:31

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.

58
répondu Russell Borogove 2013-02-25 02:25:05

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('!')
8
répondu cwallenpoole 2013-02-22 20:13:54

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
3
répondu Alex Che 2017-08-06 21:23:21

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))

2
répondu dm03514 2016-06-03 10:51:19