Как правильно игнорировать исключения

Когда вы просто хотите использовать try-except без обработки исключения, как вы это делаете в Python?

Правильно ли это сделать?

try:
    shutil.rmtree(path)
except:
    pass

Ответ 1

try:
  doSomething()
except: 
  pass

или

try:
  doSomething()
except Exception: 
  pass

Разница в том, что первая из них также поймает KeyboardInterrupt, SystemExit и т.д., которые производятся непосредственно из exceptions.BaseException, а не exceptions.Exception.
Подробнее см. документацию:

Ответ 2

Обычно считается, что лучше всего использовать только ошибки, которые вас интересуют. В случае с 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:

Ответ 3

Когда вы просто хотите попробовать catch, не обрабатывая исключение, как вы это делаете в Python?

Это зависит от того, что вы подразумеваете под "обработкой".

Если вы хотите поймать его, не предпринимая никаких действий, код, который вы опубликовали, будет работать.

Если вы имеете в виду, что хотите принять решение об исключении, не останавливая исключение из стека, вам нужно что-то вроде этого:

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown

Ответ 4

Сначала я цитирую ответ Джека о'Коннора из этой темы. Связанная нить закрылась, поэтому я пишу здесь:

"В 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

Ответ 5

Для полноты:

>>> 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

Ответ 6

Как правильно игнорировать исключения?

Есть несколько способов сделать это.

Однако выбор примера имеет простое решение, которое не охватывает общий случай.

Для примера:

Вместо

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)

Вы будете молча игнорировать FileNotFoundError:

>>> with suppress(FileNotFoundError):
...     shutil.rmtree('bajkjbkdlsjfljsf')
... 
>>> 

Из docs:

Как и любой другой механизм, полностью исключающий исключения, этот менеджер контекста должен использоваться только для того, чтобы покрывать очень специфические ошибки где тихое продолжение выполнения программы, как известно, является правильный предмет, чтобы сделать.

Обратите внимание, что suppress и FileNotFoundError доступны только в Python 3.

Если вы хотите, чтобы ваш код работал и на Python 2, см. следующий раздел:

Python 2 и 3:

Если вы просто хотите сделать 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 

Ответ 7

Если вы просто хотите выполнить попытку без обработки исключения, как вы это делаете в Python?

Это поможет вам напечатать, что такое исключение :( то есть попробуйте перехватить без обработки исключения и распечатать исключение.)

import sys
try:
    doSomething()
except:
    print "Unexpected error:", sys.exc_info()[0]

Ответ 8

try:
      doSomething()
except Exception: 
    pass
else:
      stuffDoneIf()
      TryClauseSucceeds()

FYI предложение else может идти после всех исключений и будет выполняться только в том случае, если код в try не вызывает исключения.

Ответ 9

В 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...

Ответ 10

Мне нужно было игнорировать ошибки в нескольких командах, и fuckit сделал трюк

import fuckit

@fuckit
def helper():
    print('before')
    1/0
    print('after1')
    1/0
    print('after2')

helper()

Ответ 11

Обработка исключения в Python: если у вас есть подозрительный код, который может вызвать исключение, вы можете защитить свою программу, поставив подозрительный код в блок try:.

try:
    # Your statements .............
except ExceptionI:
    # Your statements.............
except ExceptionII:
    # Your statements..............
else:
   # Your statements

Ответ 12

Просто поднимите соответствующее исключение, просто так:

try:
     raise NameError('Joan')
 except NameError:
     print 'An exception just raised again by Joan!'
     raise

Так просто. :)

Для получения дополнительной информации прочитайте эту документацию: https://docs.python.org/3.6/tutorial/errors.html