Рекомендации по исключениям Python?


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

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

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

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

    def __str__(self):
        return "[ERROR] %sn" % 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] %sn" % str(self.message)
        if(self.reason != None):
            ret += "[REASON] %sn" % str(self.reason)
        return ret

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

4 55

4 ответа:

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

что?

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

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


Edit

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

raise "SomeNameOfAnExceptionClass"

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

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

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

некоторые ключевые моменты в блог:

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

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

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

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

...

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

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

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

...

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

Я считаю, что Совет против создания исключений со строкой исходит из "обучения Python" (O'Reilly). В разделе под названием Строка Исключения Прямо!, он указывает на (Теперь удаленную) возможность создания исключения непосредственно с произвольной строкой.

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

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

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

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

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

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

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

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

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

лично я стараюсь избегать всего, что выходит за рамки

class SomeException(Exception): pass

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