Когда вы просто хотите использовать try-except без обработки исключения, как вы это делаете в Python?
Правильно ли это сделать?
try:
shutil.rmtree(path)
except:
pass
Когда вы просто хотите использовать try-except без обработки исключения, как вы это делаете в Python?
Правильно ли это сделать?
try:
shutil.rmtree(path)
except:
pass
try:
doSomething()
except:
pass
или
try:
doSomething()
except Exception:
pass
Разница в том, что первая из них также поймает KeyboardInterrupt
, SystemExit
и т.д., которые производятся непосредственно из exceptions.BaseException
, а не exceptions.Exception
.
Подробнее см. документацию:
Обычно считается, что лучше всего использовать только ошибки, которые вас интересуют. В случае с 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 found" - вы, вероятно, не хотите игнорировать это, что может быть сложно отладить.
Если вы определенно хотите игнорировать все ошибки, перехватите Exception
а не голый, except:
statement. Опять же, почему?
Не указывая исключение, вылавливает каждое исключение, включая исключение 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 an unexpected error
raise
Вы также можете import errno
и изменить if
if e.errno == errno.ENOENT:
Когда вы просто хотите попробовать 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)
Так как это охватывает только узкий пример примера, я еще раз продемонстрирую, как это сделать, если эти аргументы ключевого слова не существовали.
Так как приведенное выше охватывает только узкий пример примера, я еще раз продемонстрирую, как справиться с этим, если эти аргументы ключевого слова не существовали.
Вы можете импортировать контекстный менеджер suppress
:
from contextlib import suppress
Но только подавляйте наиболее конкретное исключение:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Вы будете молча игнорировать FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Из docs:
Как и любой другой механизм, полностью исключающий исключения, этот менеджер контекста должен использоваться только для того, чтобы покрывать очень специфические ошибки где тихое продолжение выполнения программы, как известно, является правильный предмет, чтобы сделать.
Обратите внимание, что suppress
и FileNotFoundError
доступны только в Python 3.
Если вы хотите, чтобы ваш код работал и на Python 2, см. следующий раздел:
Если вы просто хотите сделать try/except без обработки исключения, как вы это делаете в 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
Если вы просто хотите выполнить попытку без обработки исключения, как вы это делаете в Python?
Это поможет вам напечатать, что такое исключение :( то есть попробуйте перехватить без обработки исключения и распечатать исключение.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
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...
Мне нужно было игнорировать ошибки в нескольких командах, и fuckit сделал трюк
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
Обработка исключения в Python: если у вас есть подозрительный код, который может вызвать исключение, вы можете защитить свою программу, поставив подозрительный код в блок try:.
try:
# Your statements .............
except ExceptionI:
# Your statements.............
except ExceptionII:
# Your statements..............
else:
# Your statements
Просто поднимите соответствующее исключение, просто так:
try:
raise NameError('Joan')
except NameError:
print 'An exception just raised again by Joan!'
raise
Так просто. :)
Для получения дополнительной информации прочитайте эту документацию: https://docs.python.org/3.6/tutorial/errors.html