Вопрос-Ответ

How to properly ignore exceptions

Как правильно игнорировать исключения

Когда вы просто хотите выполнить try-except без обработки исключения, как вы делаете это на Python?

Правильный ли способ сделать это следующим образом?

try:
shutil.rmtree(path)
except:
pass
Переведено автоматически
Ответ 1
try:
doSomething()
except Exception:
pass

или

try:
doSomething()
except:
pass

Разница в том, что второй также будет перехватывать KeyboardInterrupt, SystemExit и тому подобное, которые являются производными непосредственно от BaseException, а не Exception.

Подробности смотрите в документации:

Однако, как правило, перехватывать каждую ошибку - плохая практика - см. Почему "except: pass" - плохая практика программирования?

Ответ 2

Обычно считается, что лучше всего перехватывать только те ошибки, которые вас интересуют. В случае с shutil.rmtree это, вероятно, OSError:

>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'

Если вы хотите молча игнорировать эту ошибку, вам следует сделать:

try:
shutil.rmtree(path)
except OSError:
pass

Почему? Допустим, вы (каким-то образом) случайно передаете функции целое число вместо строки, например:

shutil.rmtree(2)

Это выдаст ошибку "TypeError: приведение к Unicode: нужна строка или буфер, найден int" - вероятно, вы не захотите игнорировать это, что может быть сложно отладить.

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

Без указания исключения перехватывается каждое исключение, включая SystemExit исключение, которое, например, sys.exit() использует:

>>> try:
... sys.exit(1)
... except:
... pass
...
>>>

Сравните это со следующим, который корректно завершает:

>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$

Если вы хотите написать код с более совершенным поведением, то OSError исключение может представлять различные ошибки, но в приведенном выше примере мы хотим только игнорировать Errno 2, поэтому мы могли бы быть еще более конкретными:

import errno

try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise
Ответ 3

Сначала я процитирую ответ Джека о'Коннора из этой темы. Упомянутый поток был закрыт, поэтому я пишу здесь:

"В Python 3.4 появился новый способ сделать это:

from contextlib import suppress

with suppress(Exception):
# your code

Вот коммит, который добавил это: http://hg.python.org/cpython/rev/406b47c64480

А вот и автор, Рэймонд Хеттингер, рассказывающий об этом и всевозможных других новинках Python: https://youtu.be/OSGv2VnC0go?t=43m23s

Мое дополнение к этому - эквивалент Python 2.7:

from contextlib import contextmanager

@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass

Затем вы используете его, как в Python 3.4:

with ignored(Exception):
# your code
Ответ 4

Когда вы просто хотите выполнить try catch без обработки исключения, как вы делаете это на Python?


Это зависит от того, что вы подразумеваете под "обработкой".

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

Если вы имеете в виду, что хотите выполнить действие с исключением, не останавливая продвижение исключения по стеку, то вам нужно что-то вроде этого:

try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
python