Если вы просто хотите попробовать, кроме как обработать исключение, как вы это делаете в Python?
Является ли следующий способ сделать это правильно?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Если вы просто хотите попробовать, кроме как обработать исключение, как вы это делаете в Python?
Является ли следующий способ сделать это правильно?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Ответы:
try:
doSomething()
except:
pass
или
try:
doSomething()
except Exception:
pass
Разница в том, что первый тоже будет ловить KeyboardInterrupt
, SystemExit
и тому подобные вещи, которые получены напрямую exceptions.BaseException
, а не exceptions.Exception
.
Подробности смотрите в документации:
try: shuti.rmtree(...) except: pass
будет грубо подавлять любые ошибки (даже если вы ошиблись в shutil
результате а NameError
) - по крайней мере, делатьexcept OSError:
Как правило, рекомендуется отлавливать только те ошибки, которые вас интересуют. В случае 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
лучше использовать catch, а не просто 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
shutil.rmtree
это не лучший пример, потому что вы просто использовали бы ignore_errors=True
для этой функции ..
Если вы просто хотите выполнить попытку без обработки исключения, как вы это делаете в 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")
Также обратите внимание, что вы можете захватить исключение следующим образом:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... и повторно вызвать исключение следующим образом:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... примеры из учебника по питону .
Как правильно игнорировать исключения?
Есть несколько способов сделать это.
Однако выбор примера имеет простое решение, которое не распространяется на общий случай.
Вместо
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')
...
>>>
Из документов :
Как и с любым другим механизмом, который полностью подавляет исключения, этот диспетчер контекста следует использовать только для покрытия очень специфических ошибок, когда, как известно, правильное выполнение молчаливого продолжения выполнения программы.
Обратите внимание, что suppress
и FileNotFoundError
доступны только в Python 3.
Если вы хотите, чтобы ваш код работал и в Python 2, см. Следующий раздел:
Если вы просто хотите сделать попытку / исключение без обработки исключения, как вы это делаете в 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()
Кстати, предложение else может идти после всех исключений и будет выполняться только в том случае, если код в попытке не вызывает исключение.
else
в этом контексте. И добавить, что всегдаfinally
будет работать после любого (или без исключения).
Мне нужно было игнорировать ошибки в нескольких командах и fuckit сделал свое дело
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
В 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:
doSomething()
except:
_ = ""
_ = ""
на pass
.
shutil.rmtree(path, ignore_errors=True)
. Однако это не относится к большинству функций.