Как сделать python изящно терпит неудачу?

Мне просто интересно, как сделать python ошибкой определенным пользователем во всех возможных ошибках.

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

Если кто-нибудь может мне помочь с этим, будем очень благодарны!

Спасибо большое!

Джейсон

Ответ 1

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

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

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

import logging
logger = logging.getLogger()

for item in items:
    try:
        process(item)
    except Exception, exc:
        logger.warn("error while processing item: %s", exc)

Совет 3. Определите "исключение приложения", в конце концов вы можете определить иерархию такого исключения, но это лучше обнаружить, когда возникнет такая необходимость. Используйте такое исключение (-ы) для "пузырирования", когда данные, с которыми вы имеете дело, не являются тем, что вы ожидали, или чтобы сигнализировать о непоследовательных ситуациях, отделяя их от обычного стандартного исключения, возникающего из-за регулярных ошибок или проблем за пределами смоделированного домена (ошибки ввода-вывода и т.д.).

class DomainException(Exception):
    """Life is not what I expected"""

def process(item):
    # There is no way that this item can be processed, so bail out quickly.
    # Here you are assuming that your caller will report this error but probably
    # it will be able to process the other items.
    if item.foo > item.bar:
        raise DomainException("bad news")

    # Everybody knows that every item has more that 10 wickets, so
    # the following instruction is assumed always being successful.
    # But even if luck is not on our side, our caller will be able to
    # cope with this situation and keep on working
    item.wickets[10] *= 2

Основная функция - это крайняя контрольная точка: наконец, рассмотрим возможные пути завершения вашей задачи. Если это не оболочка script (но, например, обработка под диалогом в приложении пользовательского интерфейса или операция после POST в веб-приложении), то только то, как вы сообщаете об ошибке, изменяется (и использование метода ведения журнала полностью разделяет реализация обработки с его интерфейса).

def main():
    try:
        do_all_the_processing()
        return 0
    except DomainException, exc:
        logger.error("I couldn't finish. The reason is: %s", exc)
        return 1
    except Exception, exc:
        logger.error("Unexpected error: %s - %s", exc.__class__.__name__, exc)
        # In this case you may want to forward a stacktrace to the developers via e-mail
        return 1
    except BaseException:
        logger.info("user stop") # this deals with a ctrl-c
        return 1

if __name__ == '__main__':
    sys.exit(main())

Ответ 2

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

Хорошим местом для начала является раздел Python по исключениям.

В принципе, вам нужно обернуть свой код в блок try...except следующим образом:

try:
    do_something_dangerous()
except SomeException:
    handle_the_error()

Ответ 3

использовать try... except idiom

try:
    # code that possibly breaks
except RelevantError:          # you need to know what kind of errors you code might produce
    # show your message

Ответ 4

все возможные ошибки

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

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

Ответ 5

Когда Python переходит в состояние ошибки, он выдает исключение.

Способ справиться с этим состоит в том, чтобы поймать исключение и, возможно, обработать его.

Вы можете проверить раздел об исключениях на python tutorial.

Вы выразили заинтересованность в ловле всех исключений. Это можно сделать, поймав класс Exception. в соответствии с документацией:

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