Python "open()" выдает разные ошибки для "файла не найден" - как обрабатывать оба исключения?
У меня есть script, когда пользователю предлагается ввести имя файла (файла, который должен быть открыт), и если файл не существует в текущем каталоге, пользователь будет запрошен снова. Вот короткая версия:
file = input("Type filename: ")
...
try:
fileContent = open(filename, "r")
...
except FileNotFoundError:
...
Когда я тестировал свой script на моем 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
, который я обычно не хочу.
Ответы
Ответ 1
В 3.3, IOError
стал псевдонимом для OSError
, а FileNotFoundError
является подклассом OSError
. Поэтому вы можете попробовать
except (OSError, IOError) as e:
...
Это приведет к созданию довольно широкой сети, и вы не можете предположить, что исключение - "файл не найден" без проверки e.errno
, но он может охватывать ваш прецедент.
PEP 3151 обсуждает обоснование для изменения подробно.
Ответ 2
Это кажется мне лучше, чем простой except:
, но я не уверен, что это лучшее решение:
error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError)
try:
f = open('.....')
except error_to_catch:
print('!')
Ответ 3
вы можете одновременно поймать 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))
Ответ 4
Итак, чтобы точно поймать, только когда файл не найден, я делаю:
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