# Мы снова забыли объявить bar()... 1
См. документацию Python «Модуль abc»:
https://docs .python .org/3/library/abc .html
128 Глава 4 • Классы и ООП
Этот фрагмент кода по-прежнему ведет себя так, как нужно, и создает
правильную иерархию классов:
assert issubclass(Concrete, Base)
С другой стороны, мы здесь получаем еще одно преимущество. Подклас-
сы
Base
вызывают исключение
TypeError
во время создания экземпляра всякий раз, когда мы забываем реализовать какие-либо абстрактные
методы. Вызванное исключение говорит о том, какой метод или методы
отсутствуют:
>>> c = Concrete()
TypeError:
"Can't instantiate abstract class Concrete with abstract methods bar" Без модуля
abc
мы получали бы только исключение
NotImplementedError
в случае фактического вызова отсутствующего метода. Возможность
получать уведомления об отсутствующих методах во время создания эк-
земпляра является большим преимуществом. В результате написание не-
допустимых подклассов в значительной степени блокируется. Возможно,
этот факт не сыграет какой-то особой роли, если вы пишете новый код, но
обещаю, что спустя несколько недель или месяцев он станет полезным.
Безусловно, этот шаблон не является полной заменой проверки типов во
время компиляции. Однако я обнаружил, что он часто делает иерархии
классов более прочными и более удобными в сопровождении. Использо-
вание абстрактных классов позволяет программисту четче формулировать
свой замысел и таким образом делает код более коммуникативным. Я ре-
комендую вам почитать документацию по модулю
abc
и присмотреться
к ситуациям, где применение этого шаблона имеет смысл.
Ключевые выводы
Абстрактные классы (АК) следят за тем, чтобы производные классы
реализовывали те или иные методы базового класса во время создания
экземпляра.
Применение АК помогает избежать ошибок и сделать иерархии клас-
сов более легкими в сопровождении.
4 .6 . Чем полезны именованные кортежи 129 4 .6 . Чем полезны именованные кортежи
Python поставляется со специализированным контейнерным типом
namedtuple
, то есть именованным кортежем. И этот тип, по всей видимо-
сти, не привлекает того внимания, которое он заслуживает. Именованный
кортеж представляет собой одно из тех удивительных функциональных
средств языка Python, которое спрятано у всех на виду.
Именованные кортежи могут быть отличной альтернативой определению
класса вручную, и у них есть некоторые другие интересные свойства,
с которыми я хочу вас познакомить в этом разделе.
Итак, что же такое именованный кортеж и в чем проявляется его ис-
ключительность? Именованные кортежи лучше всего представить как
расширение встроенного типа данных
tuple
.
Кортежи Python — это простая структура данных, предназначенная для
группирования произвольных объектов. Кроме того, кортежи не могут
изменяться — после их создания их нельзя изменять. Ниже приведен
короткий пример:
>>> tup = ('привет', object(), 42)
>>> tup
('привет',
130 Глава 4 • Классы и ООП
Именованные кортежи спешат на помощь
Именованные кортежи призваны решать эти две проблемы.
В первую очередь именованные кортежи являются неизменяемыми
контейнерами, точно так же, как обычные кортежи. Поместив данные
в атрибут верхнего уровня в именованном кортеже, вы не сможете его
модифицировать путем обновления этого атрибута. Все атрибуты объекта
namedtuple
подчиняются принципу «однократная запись, многократное
чтение».
Помимо этого, контейнеры типа
namedtuple
являются, скажем так, име-