Python "open()" выдает разные ошибки для "файл не найден" - как обрабатывать оба исключения?
У меня есть сценарий, в котором пользователю предлагается ввести имя файла (файла, который должен быть открыт), и если файл не существует в текущем каталоге, пользователю предлагается снова. Вот короткая версия:
file = input("Type filename: ")
...
try:
fileContent = open(filename, "r")
...
except FileNotFoundError:
...
Когда я тестировал мой скрипт на моем MacOS X в Python 3.3x, он прекрасно работал, когда я специально набираю неправильное имя файла (он выполняет набор под "ожидаемо").
Однако, когда я хотел запустить свой код на компьютере Windows в Python 3.2x, я получаю сообщение об ошибке, в котором говорится, что "FileNotFoundError" не определен. Итак, Python 3.2 в Windows считает, что "FileNotFoundError" является переменной, и программы завершают работу с ошибкой.
Я понял, что Python 3.2 в Windows выдает "IOError", если имя входного файла недопустимо. Я протестировал его на своем компьютере с Linux в Python 2.7, и это также IOError.
Моя проблема в том, что код с
except "FileNotFoundError":
не будет работать на Windows Python 3.2, но если я изменю его на
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))