我有两个基类
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
类型,它实际上有一个 t,但我明确告诉 mypy 否则。
问题是:
dB.a
是 dA
类型?我需要使用 TypeVar 吗?我发现了问题mypy:基类没有属性x,如何在基类中键入提示,但是,扩展基类的解决方案是不可行的,因为这将使
t
在所有派生类中可用,不仅是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
。
在此实例中,您可以通过执行以下操作来指定
self.a
的类型;
class dB(B):
a: dA
... # Rest as before
应该指出的是,我无法复制OP提供的代码,因为
mypy
抱怨super
中dB
的第二个参数与参数1不是同一实例。尽管如此,这应该对你有用,就像我在类似的情况下一样。