Использовать Optional в абстрактных классах или нет?
Опубликовано 06 September 2018 в Python
Подсказки типов в Python необязательны: вы вольны выбирать пользоваться или ими или нет. Но начав включать их в свой код, точно возникнут определенныме трудности аннотирования функций или переменных. Эта статья — моя точка зрения на один специфический случай.
К примеру, имеется иерархия классов, которая выглядит похожей на ту, что представлена в коде ниже. Это, может быть, какой-то маппинг в базу или иерархия команд. Самая важная часть в этом примере то, что имеется один абстрактный класс и несколько реальных классов, его наследников. Не так важно помечен ли этот абстрактный класс специальным образом или нет. Я просто предполагаю, что он используется в качестве такового.
class A:
arrt = None
class B(a):
arrt = 'B'
Как вы заметили, у класса есть один атрибут, который должен быть строкой во всех реальных классах. И нет никакого вменяемого значения для этого атрибута в абстрактном классе. Использовать пустую строку также нельзя.
Есть два варианта добавления подсказки по типам, кроме Any
, конечно: использовать Optional
или нет. Давайте обсудим первый вариант.
class A:
arrt = None # type: Optional[str]
Выглядит хорошо. Но есть одна проблема: значение атрибута может быть или строкой или None
. Такой класс будет соответствовать по типам:
class C(A):
attr = None
Но это не то поведение, которое требовалось. Нашей целью было избежать этого.
Второй вариант без Option
работает много лучше.
class A:
arrt = None # type: str
Если описать типы так, то класс C
не пройдет проверку mypy: как раз необходимый нам результат.
Подсказки типов в Python вещь дополнительная. Динамическая природа и легаси код вызывают проблемы время от времени. Optional
— иногда хороший выбор, но не всегда.
Возник вопрос? Мне всегда можно написать в Twitter: avkorablev