4 .3 . Определение своих
собственных классов-исключений 117
class NameTooLongError(BaseValidationError):
pass
class NameTooCuteError(BaseValidationError):
pass
Например, это позволяет пользователям вашего пакета писать инструк-
ции
try-except
, которые могут обработать все ошибки, возникающие в ре-
зультате работы этого пакета, без необходимости отлавливать их вручную:
try:
validate(name)
except BaseValidationError as err:
handle_validation_error(err)
Люди по-прежнему могут отлавливать более конкретные виды исключений
этим способом, но если они этого не хотят, то, по крайней мере им не при-
дется прибегать к захватыванию всех исключений при помощи всеобъем-
лющей инструкции
except
. Обычно такой подход считается антишаблоном
проектирования — он может негласно поглотить и скрыть разрозненные
ошибки и сделать ваши программы намного труднее для отладки.
Разумеется, вы можете развить эту идею и логически сгруппировать ис-
ключения в подробнейшие субиерархии. Но будьте осторожны — можно
очень легко
внести ненужную сложность, переборщив с этой работой.
Подводя итоги, следует отметить, что определение собственных классов-
исключений облегчает принятие вашими пользователями стиля про-
граммирования «Легче попросить прощения, чем разрешения» (EAFP),
который считается более питоновским.
Ключевые
выводы
Определение ваших собственных типов исключений позволяет яснее
сформулировать замысел вашего программного кода и облегчить его
отладку.
Следует делать свои собственные исключения производными от встро-
енного в Python класса
Exception
или от более конкретных классов-
исключений,
таких как
ValueError
или
KeyError
.
118 Глава 4 • Классы и ООП
Для определения логически сгруппированных иерархий исключений
можно использовать наследование.
4 .4 . Клонирование
объектов
для дела и веселья
В Python инструкции присваивания не создают копии объектов, они лишь
привязывают имена к объекту. Для неизменяемых объектов этот факт
обычно не имеет значения.
Но для работы с изменяемыми объектами или коллекциями изменяемых
объектов вам, возможно, стоит найти способ создания «реальных копий»,
или «клонов», этих объектов.
По существу, вам иногда будут требоваться копии, которые можно моди-
фицировать
без автоматической модификации оригинала. В этом разделе
я кратко представлю то, как копировать, или «клонировать», объекты
в Python, и покажу связанные с этим подводные камни.
Начнем с того, что обратимся к копированию встроенных в Python кол-
лекций. Встроенные в Python изменяемые коллекции, такие как списки,
словари и множества, могут быть скопированы путем вызова своих фа-
бричных функций с существующей коллекцией в качестве аргумента:
new_list = list(original_list)
new_dict = dict(original_dict)
new_set = set(original_set)
Однако этот метод не будет работать с собственными объектами и, вдо-
бавок ко всему, он создает только
мелкие копии. Для составных объектов,
таких как списки, словари и множества, между
мелким и
глубоким копи-
рованием имеется важное различие.
Do'stlaringiz bilan baham: