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

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

Является ли следующий правильный способ сделать это?

try:
    shutil.rmtree(path)
except:
    pass

14 ответов

Решение
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 найдена" - вы, вероятно, не хотите игнорировать это, что может быть трудно отладить.

Если вы определенно хотите игнорировать все ошибки, поймайте 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 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

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

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

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

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

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

Для полноты:

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

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

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

Из документов:

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

Обратите внимание, что 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 библиотека, и ререйз, если у нас его нет:

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 

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

import fuckit

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

helper()

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

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

импорт системы....
пытаться:
    сделай что-нибудь()
Кроме:
    выведите "неожиданная ошибка:", sys.exc_info()[0]

...

рег, Тилокчан

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

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

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

Что ж, это не попытка, а еще один способ обработки исключений, если вам нравится объектно-ориентированное программирование:

      class MyExceptionHandler:

    def __enter__(self):
        ... # Do whatever when "with" block is started
        return self

    def __exit__(self, exc_type, exc_value, tb):
        return True

А затем к собственному коду:

      with MyExceptionHandler():
     ... # Code that may or may not raise an exception
     shutil.rmtree(path)

Как это работает?

  • __enter__ запускается при входе в блок.
  • __exit__ запускается при выходе из with блокировать
    • Это должно вернуться True чтобы заглушить возможное исключение.
    • Это должно вернуться None (или что-то, что считается ложным), чтобы не заглушить потенциальное исключение.
    • Тип исключения, фактическое исключение и его трассировка передаются как (позиционные) аргументы. Вы можете использовать их, чтобы определить, что делать.

В заключение, предпочтение отдается try-except. Это может быть полезно, если вам нужно больше абстракции, чем обычно.

Обработка исключения в 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

Обычно я просто делаю:

try:
    doSomething()
except:
    _ = ""
Другие вопросы по тегам