Как игнорировать все возможные исключения в Python?

Я пишу собственный скрипт резервного копирования на Python. Иногда функция mkdir или функция печати или любая другая функция не работает по разным причинам. Такие исключения останавливают весь сценарий и останавливают резервное копирование в середине, что очень неприятно. До сих пор я справлялся с этими проблемами, добавляя операторы try: ... exclude: ... и правильно управляя этими исключениями. Однако в один прекрасный день какой-то другой оператор или функция также могут вызвать исключение из-за какой-то другой причины, которая еще не была запущена.

Есть ли способ указать сценарию все равно продолжать работу? Эквивалент переноса каждого отдельного оператора кода в предложение try: ... кроме: pass? Лог, конечно, лучше.

Я заметил, что при программировании с помощью инструментов с графическим интерфейсом, таких как Tkinter, приложение продолжает работать, даже если возникают исключения. Возможно ли сделать что-то подобное с помощью консоли?


person Andy    schedule 22.11.2015    source источник
comment
Вместо того, чтобы оборачивать каждый оператор в блоки try...except, вам, вероятно, следует выполнять больше проверки и тестирования в своем коде. Если функция зависит от входного списка из 5 элементов, проверьте, что список имеет 5 элементов.   -  person MattDMo    schedule 23.11.2015
comment
Это несколько не по-питоновски, так как это прямо противоречит тому разрешению, которое было проще попросить прощения.   -  person Tom Dalton    schedule 23.11.2015
comment
То, что вы спрашиваете, не имеет никакого смысла. Скажем, функция mkdir не удалась; если вы проигнорировали исключение, что вы ожидаете от кода, который намеревался использовать этот каталог?   -  person Daniel Roseman    schedule 23.11.2015
comment
@TomDalton: Как раз то, о чем я думал! См. раздел EAFP и LBYL.   -  person Falko    schedule 23.11.2015
comment
Возможный дубликат Python: о перехвате ЛЮБОГО исключения   -  person Pynchia    schedule 23.11.2015


Ответы (6)


У Python нет возможности сделать это, и на то есть веские причины.

Кажется, вы не понимаете, что значит писать «надежное» программное обеспечение: надежная программа — это не программа, которую трудно убить и которая будет продолжать работать несмотря ни на что, а программа, которая будет правильно обрабатывать крайние случаи. Недостаточно просто продолжать бегать... Ключевым моментом является делать разумные вещи.

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

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

Также обратите внимание, что каждый catch потенциально является источником ошибок... например:

try:
    print my_dict[foo()]
except KeyError:
    ...

не может различить, идет ли KeyError для доступа к несуществующему ключу в my_dict или вместо этого экранируется от foo(). Редко два случая должны обрабатываться одинаково...

Лучше написать:

key = foo()
if key in my_dict:
    print my_dict[key]
else:
    ...

так что обрабатывается только побочный случай отсутствия ключа в my_dict, и вместо этого исключение KeyError останавливает программу (остановка программы, когда вы не уверены в том, что она делает, - единственная разумная вещь).

person 6502    schedule 22.11.2015
comment
Легче попросить прощения, чем разрешения. Этот общий стиль кодирования Python предполагает наличие действительных ключей или атрибутов и перехватывает исключения, если предположение оказывается ложным. Этот чистый и быстрый стиль характеризуется наличием множества операторов try и exclude. Этот метод контрастирует со стилем LBYL, общим для многих других языков, таких как C. ~ python docs - person l__flex__l; 19.01.2017

На самом деле есть модуль, который должен делать именно это: https://github.com/ajalt/fuckitpy.

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

Вместо этого вам следует определить, какие строки кода могут вызывать какие ошибки, и обрабатывать эти ошибки должным образом. Существует очень много мест, где действительно могут произойти ошибки — в основном при взаимодействии с внешними системами, включая файловую систему, сеть, пользовательский ввод и т. д. И помните, что фактический сбой часто лучше, чем продолжать «работу» и испортить ваши данные, файлы и т. д. на. Исключения есть по какой-то причине, они не являются результатом злого умысла Гвидо.

person letitbee    schedule 22.11.2015

Python имеет «BaseException» в качестве базового класса для классов исключений. Вы можете поймать и проигнорировать Exception базового класса, и это будет охватывать все исключения.

try
    ... your code here ...
except BaseException as exp:
    print "A General Exception Occurred"
person Kanwar Saad    schedule 22.11.2015
comment
За исключением нескольких специальных, таких как KeyboardInterrupt — см. docs.python.org/3. /library/exceptions.html#exception-hierarchy - person Tom Dalton; 23.11.2015
comment
Но на самом деле, если вы проглатываете прерывания клавиатуры, ЧТО вы пишете? :-) - person Paul Gowder; 23.11.2015
comment
BaseException покроет все... Я обновил ответ - person Kanwar Saad; 23.11.2015

try:
   # code segment
except:
   pass

Ключевое слово pass будет игнорировать все исключения

person BasuruK    schedule 10.05.2017

Обычно этот должен ловить все:

try:
   ....
except:
   pass

Единственная проблема в том, что вы не получаете объект исключения с этим синтаксисом, но в данном случае это не запрашивалось.

person Juergen    schedule 22.11.2015

Вы можете добавить общий блок, кроме как предложенный @Kanwar Saad. Вопрос в том, можете ли вы продолжить свою программу в допустимом состоянии после того, как возникнет исключение?

Из дзен Python:

Errors should never pass silently.
Unless explicitly silenced.

Попытка поймать все исключения, которые вы знаете, на мой взгляд, лучший способ пойти сюда. Если вы не можете явно поймать исключение, вы не должны пытаться его обойти. Вы (и ваши пользователи) должны знать, что именно пошло не так, иначе ваш код может превратиться в кошмар для отладки.

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

def save_unfinished_backup():
    # try to find a graceful exit without losing any data

try:
    # some code
except OSError:
    # handle oS Errors
except Exception:
    save_unfinished_backup()
    raise

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

Надеюсь, это поможет!


Забавное примечание: вы также можете использовать модуль fuckit. Который замалчивает ВСЕ ошибки, включая синтаксические ошибки. Однако никогда не используйте это в продуктивном коде.

Это должно работать отлично. Он не напечатает «foo», но вы доберетесь до print("bar") без сбоев.

import fuckit

with fuckit:
    prnt("foo")

print("bar")
person m00am    schedule 22.11.2015