Как правильно игнорировать исключения
когда вы просто хотите попробовать-кроме как без обработки исключения, как вы это делаете в Python?
следующий правильный способ сделать это?
try:
shutil.rmtree(path)
except:
pass
11 ответов:
try: doSomething() except: pass
или
try: doSomething() except Exception: pass
разница в том, что первый тоже будет ловить
KeyboardInterrupt
,SystemExit
и тому подобное, которые выводятся непосредственно изexceptions.BaseException
, а неexceptions.Exception
.
Подробнее см. документацию:
- попробуйте заявление -http://docs.python.org/reference/compound_stmts.html#try
- исключения -http://docs.python.org/library/exceptions
обычно считается лучшей практикой ловить только те ошибки, которые вас интересуют. В случае
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 найден" - вы вероятно, не хочу игнорировать это, что может быть трудно отладить.
если вы наверняка хочу, чтобы игнорировать все ошибки, поймать
Exception
а не голыеexcept:
заявление. Опять же, почему?не указывая исключение ловит исключения, в том числе
SystemExit
исключение, которое, например,sys.exit()
применение:>>> try: ... sys.exit(1) ... except: ... pass ... >>>
сравните это со следующим, который правильно выходит:
>>> try: ... sys.exit(1) ... except Exception: ... pass ... shell:~$
если вы хотите чтобы написать когда-либо лучше себя вести код,
OSError
исключение может представлять различные ошибки, но в приведенном выше примере мы хотим только игнорироватьErrno 2
, так что мы могли бы быть еще более конкретными:try: shutil.rmtree(path) except OSError, e: if e.errno == 2: # suppress "No such file or directory" error pass else: # reraise the exception, as it's an unexpected error raise
вы могли бы также
import errno
, иif
доif e.errno == errno.ENOENT:
когда вы просто хотите сделать попытку поймать без обработки исключения, как вы делаете это в Python?
Это зависит от того, что вы подразумеваете под "обработкой."
Если вы хотите поймать его без каких-либо действий, код, который вы опубликовали, будет работать.
Если вы имеете в виду, что вы хотите принять меры по исключению, не останавливая исключение от перехода в стек, то вы хотите что-то вроде этого:
try: do_something() except: handle_exception() raise #re-raise the exact same exception that was thrown
сначала я цитирую ответ Джека о'Коннора из этой теме. Ссылочный поток закрылся, поэтому я пишу здесь:
" есть новый способ сделать это в Python 3.4:
from contextlib import suppress with suppress(Exception): # your code
вот фиксация, которая добавила его:http://hg.python.org/cpython/rev/406b47c64480
и вот автор, Раймонд Хеттингер, говорит об этом и всяких других горячих питонах: 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
комплектность:
>>> def divide(x, y): ... try: ... result = x / y ... except ZeroDivisionError: ... print "division by zero!" ... else: ... print "result is", result ... finally: ... print "executing finally clause"
...из python tutorial.
также обратите внимание, что вы можете захватить исключение следующим образом:
>>> try: ... this_fails() ... except ZeroDivisionError as detail: ... print 'Handling run-time error:', detail
Как правильно игнорировать исключения?
есть несколько способов сделать это.
однако выбор примера имеет простое решение, которое не охватывает общий случай.
конкретный пример:
вместо
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)
вы будете молча игнорировать a
FileNotFoundError
:>>> with suppress(FileNotFoundError): ... shutil.rmtree('bajkjbkdlsjfljsf') ... >>>
С docs:
как и любой другой механизм, который полностью подавляет исключения, этот контекстный менеджер должен использоваться только для покрытия очень специфических ошибок где молчаливое продолжение выполнения программы, как известно, является правильно делать.
отметим, что
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
библиотека, и reraise, если у нас нет этого: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
@когда вы просто хотите сделать попытку поймать без обработки исключения, как вы это делаете в Python?
Это поможет вам напечатать, что такое исключение: (т. е. попробуйте поймать без обработки исключения и распечатать исключение.)
import sys .... try: doSomething() except: print "Unexpected error:", sys.exc_info()[0] ...reg, Тилокчан
try: doSomething() except Exception: pass else: stuffDoneIf() TryClauseSucceeds()
FYI предложение else может идти после всех исключений и будет выполняться только в том случае, если код в try не вызывает исключения.
в Python мы обрабатываем исключения, подобные другим языкам, но разница заключается в некоторой синтаксической разнице, например,
try: #Your code in which exception can occur except <here we can put in a particular exception name>: # We can call that exception here also, like ZeroDivisionError() # now your code # We can put in a finally block also finally: # Your code...
просто поднять соответствующее исключение, вот так:
try: raise NameError('Joan') except NameError: print 'An exception just raised again by Joan!' raise
вот так просто. :)
для получения более подробной информации, прочитайте эту документацию: https://docs.python.org/3.6/tutorial/errors.html
обработка исключения в Python: Если у вас есть какой-то подозрительный код, который может вызвать исключение, вы можете защитить свою программу, поместив подозрительный код в try: block.
try: # Your statements ............. except ExceptionI: # Your statements............. except ExceptionII: # Your statements.............. else: # Your statements