Python " open () "выдает разные ошибки для" file not found " - как обрабатывать оба исключения?

у меня есть скрипт, где пользователю предлагается ввести имя файла (файла, который должен быть открыт), и если файл не существует в текущем каталоге, пользователю предлагается снова. Вот краткая версия:

file = input("Type filename: ")

...
try:
    fileContent = open(filename, "r")
    ...
except FileNotFoundError:
    ...

когда я тестировал свой скрипт на моем MacOS X в Python 3.3 x, он работал отлично, когда я специально вводил неправильное имя файла (он выполняет набор в разделе "ожидать").

однако, когда я хотел запустить свой код на компьютере с Windows в Python 3.2 x, I получите ошибку, которая говорит, что" FileNotFoundError " не определен. Таким образом, Python 3.2 В Windows считает, что "FileNotFoundError" является переменной, и программы выходят с ошибкой.

Я понял, что Python 3.2 в Windows выдает "IOError", если входное имя файла недопустимо. Я тестировал его на своей машине Linux в Python 2.7, и это также IOError.

моя проблема теперь в том, что код с

except "FileNotFoundError":

не будет работать на Python 3.2 Windows, но если я изменю его на

except "IOError":

он не будет работать на моем Mac.

как я мог обойти это? Единственный способ, который я могу придумать, это использовать просто except, который я обычно не хочу.

4 ответов


В 3.3, IOError стало псевдонимом OSError и FileNotFoundError - это подкласс OSError. Так что вы можете попробовать

except (OSError, IOError) as e:
   ...

это приведет к довольно широкой сети, и вы не можете предположить, что исключение "файл не найден" без проверки e.errno, но это может покрыть ваш случай использования.

PEP 3151 подробно обсуждается обоснование изменения.


Это кажется мне лучше, чем простой except:, но я не уверен, что это лучшее решение:

error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError)

try:
    f = open('.....')
except error_to_catch:
    print('!')

Так точно поймать только тогда, когда файл не найден, я:

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

вы можете поймать 2 ошибки в то же время

except (FileNotFoundError, IOError):

Я не понял, что вы об этом спрашиваете. Я надеюсь, что есть более красноречивое решение, чем вручную проверить

try:
   error_to_catch = FileNotFoundError
except NameError:
   error_to_catch = IOError

except error_to_catch

cwallenpoole делает это условное более красноречиво в своем ответе (error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))