mypy 抱怨扩展基础 class' 属性类型
mypy complains about extended base class' attribute type
我有两个基本 classes 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
ClassA
保存了一些管理信息,而classB
保存了一些其他信息,这些信息是基于classA
,因此它知道它是 A
.
的实例
我还有两个派生的 classes 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)
这些 classes(除其他外 (dA1
、dB1
、dA2
、dB2
) ... 设计相似)被使用对于某些特殊操作,因此他们需要存储更多信息,例如这对 classes 的示例中的 t,其他 classes 有不同的东西要存储。
问题是,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: error: "A" has no attribute "t"
抱怨其实是对的。 A
没有属性 t
。我还告诉 mypy B.a
是 A
类型,但在这种特殊情况下,我使用 dB.a
作为 dA
类型,它实际上有一个 t,但我明确告诉 mypy否则。
问题是:
- 这是否违反里氏原则?
- 如果不是 1,有没有办法告诉 mypy 在这种特殊情况下
dB.a
是 dA
类型?我需要使用 TypeVar 吗?
- 如果是 1,有没有办法重构 classes 以不违反 Liskov 原则以及让类型检查器能够识别正确的类型?
我发现了问题 ,但是,扩展基础 class 的解决方案不可行,因为这会使 t
在所有派生 class 中可用es,不仅dA
(不知何故闻起来很糟糕)。
可以使用 assert:
来确保 self.a
是 dA
类型
class dB(B):
def __init__(self, a: dA):
super(A, self).__init__(a)
def do(self):
assert isinstance(self.a, dA)
if self.a.t is None:
print("something")
这个断言被 mypy 识别,因此 self.a
之后被称为 dA
的实例,因此具有属性 t
.
我有两个基本 classes 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
ClassA
保存了一些管理信息,而classB
保存了一些其他信息,这些信息是基于classA
,因此它知道它是 A
.
我还有两个派生的 classes 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)
这些 classes(除其他外 (dA1
、dB1
、dA2
、dB2
) ... 设计相似)被使用对于某些特殊操作,因此他们需要存储更多信息,例如这对 classes 的示例中的 t,其他 classes 有不同的东西要存储。
问题是,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: error: "A" has no attribute "t"
抱怨其实是对的。 A
没有属性 t
。我还告诉 mypy B.a
是 A
类型,但在这种特殊情况下,我使用 dB.a
作为 dA
类型,它实际上有一个 t,但我明确告诉 mypy否则。
问题是:
- 这是否违反里氏原则?
- 如果不是 1,有没有办法告诉 mypy 在这种特殊情况下
dB.a
是dA
类型?我需要使用 TypeVar 吗? - 如果是 1,有没有办法重构 classes 以不违反 Liskov 原则以及让类型检查器能够识别正确的类型?
我发现了问题 t
在所有派生 class 中可用es,不仅dA
(不知何故闻起来很糟糕)。
可以使用 assert:
来确保self.a
是 dA
类型
class dB(B):
def __init__(self, a: dA):
super(A, self).__init__(a)
def do(self):
assert isinstance(self.a, dA)
if self.a.t is None:
print("something")
这个断言被 mypy 识别,因此 self.a
之后被称为 dA
的实例,因此具有属性 t
.