Лучшие практики для исключений Python? - PullRequest
60 голосов
/ 08 мая 2009

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

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

Код, о котором идет речь, следующий:

"""
Base Exception, Error
"""
class Error(Exception):
    def __init__(self, message):
        self.message = message

    def __str__(self):
        return "[ERROR] %s\n" % str(self.message)

    def log(self):
        ret = "%s" % str(self.message)
        if(hasattr(self, "reason")):
            return "".join([ret, "\n==> %s" % str(self.reason)])
        return ret

class PCSException(Error):
    def __init__(self, message, reason = None):
        self.message = message
        self.reason = reason
    def __str__(self):
        ret = "[PCS_ERROR] %s\n" % str(self.message)
        if(self.reason != None):
            ret += "[REASON] %s\n" % str(self.reason)
        return ret

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

Ответы [ 5 ]

82 голосов
/ 08 мая 2009

Надежная обработка исключений (в Python) - сообщение в блоге "Лучшие практики для исключений Python", которое я написал некоторое время назад. Вы можете найти это полезным.

Некоторые ключевые моменты из блога:

Никогда не используйте исключения для управления потоком

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

Рассмотрим 'find' для строки, возвращающей -1, если шаблон не найден, но индексирование за концом строки вызывает исключение. Не найти строку - это нормальное выполнение.

Обрабатывать исключения на уровне, который знает, как их обрабатывать

...

The лучшее место - это фрагмент кода, который может обработать исключение. За некоторые исключения, такие как ошибки программирования (например, IndexError, TypeError, NameError и т. Д.) Исключения лучше оставить программисту / пользователю, потому что "обработка" их будет просто скрывать настоящие ошибки.

Всегда спрашивайте "это правильное место для обработки этого исключения?" и будьте осторожны с перехватом всех исключений.

Документирование исключений, выданных вашим кодом

...

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

33 голосов
/ 08 мая 2009

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

Что?

Пожалуйста, предоставьте ссылку или ссылку на это. Это совершенно не соответствует действительности.

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

Нет, "без строк" просто безумие в контексте Python. Возможно, вы читаете это в контексте C ++.


Редактировать

Когда-то давно (в былые времена) вы могли вызывать исключение Python по имени, а не по классу.

raise "SomeNameOfAnExceptionClass"

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

Возможно, это то, что вы прочли "Не вызывать исключение со строковым именем"

5 голосов
/ 25 ноября 2011

Я считаю, что совет против создания исключений со строкой исходит от "Learning Python" (О'Рейли). В разделе, озаглавленном Исключения строк правильны! , он указывает на (теперь удаленную) возможность создавать исключение непосредственно с произвольной строкой.

Код, который он дает в качестве примера:

myexc = "My exception string"
try:
    raise myexc
except myexc:
    print ('caught')

Это на стр. 858 четвертого издания (мягкая обложка).

4 голосов
/ 08 мая 2009

Первое впечатление, что это слишком много кода для исключения.

Форматирование исключений должно быть сделано в конфигурации регистратора. То же самое относится и к самой регистрации.

Он также переопределяет стандартный (и устаревший) атрибут сообщения и не вызывает конструктор суперкласса. (Это может или не может нарушить цепочку исключений Python 3.0, я не пробовал, потому что я работаю 2.6)

Большая часть того, что делает дополнительный код, может быть реализована с помощью BaseException.args, регистрируя следующее как «message»:

'\n==> '.join(exception.args)

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

Лично я стараюсь избегать чего-либо, кроме

class SomeException(Exception): pass

(Отказ от ответственности: ответ субъективный, возможно, по характеру вопроса.)

0 голосов
/ 18 января 2019
class Error(Exception):
    """Base class for other exceptions"""
    pass

class empty_string_error(Error):
    """Raised when the input value is too large"""
    pass
while(1):
    try:
        if("Your Condition"):
            raise empty_string_error
        else:
            print("OUTPUT")
    except empty_string_error:
        print("APT MESSAGE")
        print(" ")
    finally:
        pint("Mandatory code")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...