У меня есть два базовых класса A
и B
, которые определены следующим образом:
class A(object):
def common_function(self):
pass
class B(object):
def __init__(self, a: A):
self.a = a
def another_common_function(self):
pass
Класс A
содержит некоторую информацию управления, тогда как класс B
содержит некоторую другую информацию, котораяоснован на информации, содержащейся в классе A
, и, следовательно, он знает о своем экземпляре A
.
Мне также необходимо получить производные классы dA
и dB
, которые определены следующим образом:
class dA(A):
def __init__(self, t: B):
self.t = t
class dB(B):
def __init__(self, a: dA):
super(A, self).__init__(a)
Эти классы (среди прочих (dA1
, dB1
, dA2
, dB2
) ..., которые сконструированы аналогичным образом) используются для некоторых специальных операций и, следовательно, их необходимо хранитьнекоторая дополнительная информация, например, t из примера для этой пары классов, другие классы хранят разные вещи.
Проблема в том, что mypy жалуется на использование dB.a.t
:
class dB(B):
def __init__(self, a: dA):
super(A, self).__init__(a)
def do(self):
if self.a.t is None:
print("something")
test.py: ошибка: «A» не имеет атрибута «t»
Претензия действительно верна.A
не имеет атрибута t
.Я также сказал mypy, что B.a
имеет тип A
, но в данном конкретном случае я использую dB.a
для типа dA
, который на самом деле имеет значение at, но я явно сказал mypy в противном случае.
Вопросы:
- Это нарушение принципа Лискова?
- Если не 1, есть ли способ сообщить mypy, что в данном конкретном случае
dB.a
имеет тип dA
?Нужно ли использовать TypeVar? - Если 1, есть ли способ реструктурировать классы так, чтобы он не нарушал принцип Лискова, а также позволял ли средство проверки типов распознавать правильные типы?
Я нашел вопрос mypy: у базового класса нет атрибута x, как ввести подсказку в базовом классе , однако решение по расширению базового класса неосуществимо, так как это может сделать t
доступно во всех производных классах, не только dA
(что-то плохо пахнет).