Как правильно игнорировать исключения
когда вы просто хотите сделать попытку-за исключением обработки исключения, как вы это делаете в 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:
заявление. Опять же, почему?
не указывая исключения catches исключения, в том числе 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
to if e.errno == errno.ENOENT:
когда вы просто хотите сделать try catch без обработки исключения, как вы это делаете в 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
и вот автор, Рэймонд Хеттингер, говорит об этом и всех видах другой горячности 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
комплектность:
>>> 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 учебник.
также обратите внимание, что вы можете захватить исключение следующим образом:
>>> 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
context manager:
from contextlib import suppress
но только подавить наиболее конкретное исключение:
with suppress(FileNotFoundError):
shutil.rmtree(path)
вы будете молча игнорировать 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
это правильный способ получить утверждение, которое не-op. Но когда вы делаете голый 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
@когда вы просто хотите сделать try catch без обработки исключения, как вы это делаете в Python?
Это поможет вам напечатать, что такое исключение: (т. е. попробуйте поймать без обработки исключения и распечатать исключение.)
import sys .... try: doSomething() except: print "Unexpected error:", sys.exc_info()[0] ...
reg, Tilokchan
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