Как правильно игнорировать исключения
когда вы просто хотите попробовать-кроме как без обработки исключения, как вы это делаете в 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