Как правильно игнорировать исключения?
Есть несколько способов сделать это.
Однако выбор примера имеет простое решение, которое не охватывает общий случай.
Специфично для примера:
Вместо
try:
shutil.rmtree(path)
except:
pass
Сделайте это:
shutil.rmtree(path, ignore_errors=True)
Это аргумент, специфичный для shutil.rmtree
. Вы можете увидеть справку по ней, выполнив следующее, и вы также увидите, что она также может учитывать и ошибки.
>>> import shutil
>>> help(shutil.rmtree)
Так как это охватывает только узкий случай примера, я дополнительно продемонстрирую, как справиться с этим, если аргументы ключевого слова не существуют.
Общий подход
Поскольку вышеизложенное охватывает только узкий случай примера, я дополнительно продемонстрирую, как с этим справиться, если аргументы ключевого слова не существуют.
Новое в Python 3.4:
Вы можете импортировать менеджер контекста suppress
:
from contextlib import suppress
Но подавить только самое конкретное исключение:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Вы будете молча игнорировать FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Из документов :
Как и любой другой механизм, который полностью подавляет исключения,
этот контекстный менеджер следует использовать только для покрытия очень специфических ошибок
где молчаливое продолжение выполнения программы, как известно,
что нужно сделать.
Обратите внимание, что suppress
и FileNotFoundError
доступны только в Python 3.
Если вы хотите, чтобы ваш код работал и в Python 2, см. Следующий раздел:
Python 2 и 3:
Когда вы просто хотите попробовать / исключить, не обрабатывая исключение,
как ты это делаешь в Python?
Является ли следующий способ правильным?
try :
shutil.rmtree ( path )
except :
pass
Для кода, совместимого с Python 2, pass
- это правильный способ получить оператор, который не используется. Но когда вы делаете голый except:
, это то же самое, что и except BaseException:
, который включает в себя GeneratorExit
, KeyboardInterrupt
и SystemExit
, и вообще, вы не хотите ловить эти вещи.
На самом деле, вы должны быть как можно точнее в названии исключения.
Вот часть иерархии исключений Python (2) , и, как вы можете видеть, если вы поймете более общие исключения, вы можете скрыть проблемы, которые вы не ожидали:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Вероятно, вы хотите перехватить здесь OSError, и, возможно, вам не нужно беспокоиться об отсутствии каталога.
Мы можем получить этот конкретный номер ошибки из библиотеки errno
и повысить его, если у нас его нет:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Обратите внимание, голый рейз поднимает исходное исключение, что, вероятно, то, что вы хотите в этом случае. Написано более кратко, поскольку нам не нужно явно pass
с кодом в обработке исключений:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise