Когда я должен создать подкласс исключений в Python?

10

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

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

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

Я хотел бы услышать любой аргумент для каждого случая.

Ezra
источник
2
ЯГНИ ... Тебе это не нужно сейчас, и ты всегда можешь добавить его позже без особых проблем.
Роберт Харви
У вас есть примеры? Вы просто поднимаете Exception, например, или более конкретные встроенные ошибки?
Jonrsharpe
просто возбуждаю исключение («конкретное описание»)
Ездра
@ По крайней мере @Ezra, вы должны увидеть, есть ли более подходящее встроенное исключение (см. Docs.python.org/2/library/exceptions.html ).
Jonrsharpe

Ответы:

8

Вы правы

Аргумент в вашу сторону уже упоминается Робертом Харви: не добавляйте код, который вам сейчас не нужен, тем более что его легко добавить позже.

Ваш рецензент тоже прав

С другой стороны, мнение рецензента также понятно:

  • Возвращение универсального значения Exception()не очень полезно для вызывающей стороны: хотя описание исключения указывает человеку, что происходит, обработка исключений по-разному программно может оказаться невозможной. Разработчик, использующий ваш код, может неохотно менять типы исключений , в том числе из-за страха (оправданного или нет) что-то сломать.

    Обратите внимание, что добавление пользовательских исключений сейчас не так сложно :

    class MyCustomException(Exception):
        pass

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

  • Сам код выглядит лучше, более читабельным.

    if price < self.PriceMinValue:
        raise OutOfRangeException("The price is inferior to zero.")

    выглядит немного более читабельным по сравнению с:

    if price < self.PriceMinValue:
        raise Exception("The price is inferior to zero.")

    из-за указания типа исключения:

    • Во втором фрагменте кода мне нужно прочитать описание и предположить, что цена находится за пределами диапазона (или, возможно, это не так? Может быть, есть случаи, когда цена может быть отрицательной, например, скидки)

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

Так?

Так:

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

  • Будьте последовательны с вашей командой. Если ваша команда широко использует пользовательские исключения, используйте их.

Арсений Мурзенко
источник
2
Но есть счастливая среда raise ValueError('The price is less than zero'). Это более конкретно, чем база Exception, но без суеты.
Jonrsharpe
+1 за простое утверждение «будь последовательным», с командой, если есть, с самим собой, если нет.
Styne666