Б41 Чистый Python. Тонкости программирования для профи. Спб.: Питер



Download 6,94 Mb.
Pdf ko'rish
bet39/80
Sana24.02.2022
Hajmi6,94 Mb.
#212875
1   ...   35   36   37   38   39   40   41   42   ...   80
Bog'liq
978544610803 Chisty Python Tonko

ValueError
Этот отчет не очень-то и полезен. Несомненно, мы знаем, что что-то по-
шло не так и что проблема имела отношение к «неправильному значе-
нию» или типа того, но чтобы быть в состоянии исправить эту проблему, 
ваш коллега почти наверняка должен свериться с реализацией функции 
validate()
. Однако чтение исходного кода стоит времени. И это время 
будет быстро накапливаться.
К счастью, мы можем сделать и кое-что получше. Введем собственный 
тип исключений, который будет представлять неудавшуюся валидацию 
имени. Мы построим наш новый класс-исключение на основе встроенно-
го в Python класса 
ValueError
, но заставим его говорить за себя, дав ему 
более конкретное имя:
class NameTooShortError(ValueError):
pass 
def validate(name):
if len(name) < 10:
raise NameTooShortError(name)
Теперь у нас есть «самодокументирующий» тип исключений 
NameTooShortError
(«Имя слишком короткое»), который расширяет 
встроенный класс 
ValueError
. Обычно вы будете делать свои собственные 
исключения производными от корневого класса 
Exception
либо от других 
встроенных в Python исключений наподобие 
ValueError
или 
TypeError
— 
в зависимости от того, что кажется целесообразным.
Кроме того, обратите внимание на то, как мы теперь передаем перемен-
ную 
name
в конструктор нашего собственного класса-исключения во время 
создания его экземпляра внутри 
validate
. Новая реализация приводит 
к тому, что ваш коллега получит намного более приятный отчет об обрат-
ной трассировке:
>>> validate('джейн') 
Traceback (most recent call last):


116 Глава 4 • Классы и ООП
File "", line 1, in
validate('джейн')
File "", line 3, in validate
raise NameTooShortError(name)
NameTooShortError: джейн
Опять-таки, попытайтесь встать на место своего коллеги по команде. 
Собственные классы исключений существенно помогают понять, что 
именно происходит, когда дела идут не так, как надо (а рано или поздно 
это обязательно случится).
То же самое верно, даже если вы работаете над кодовой базой в полном 
одиночестве. Несколько недель или месяцев спустя вам будет намного 
проще выполнять сопроводительную работу, если ваш исходный код будет 
хорошо структурирован.
Потратив всего 30 секунд на определение простого класса-исключения, 
вы уже получили намного больший коммуникативный фрагмент кода. 
Но давайте пойдем дальше. Еще много чего нужно обследовать.
Всякий раз, когда вы выпускаете пакет Python в публичное пространство 
или создаете модуль многократного использования для своей компании, 
образцовая практика предусматривает создание для такого модуля соб-
ственного базового класса-исключения и затем создание производных от 
него всех других ваших исключений.
Ниже показано, как создать собственную иерархию исключений для всех 
исключений в модуле или пакете. Первый шаг состоит в объявлении ба-
зового класса, от которого наследуют все конкретные ошибки:
class BaseValidationError(ValueError):
pass
Далее, все наши «реальные» классы ошибок могут быть сделаны произ-
водными от базового класса ошибок. В результате мы получаем хорошую 
и чистую иерархию исключений, приложив лишь незначительные допол-
нительные усилия:
class NameTooShortError(BaseValidationError):
pass


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)
Однако этот метод не будет работать с собственными объектами и, вдо-
бавок ко всему, он создает только мелкие копии. Для составных объектов, 
таких как списки, словари и множества, между мелким и глубоким копи-
рованием имеется важное различие.

Download 6,94 Mb.

Do'stlaringiz bilan baham:
1   ...   35   36   37   38   39   40   41   42   ...   80




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish