我有一个关于 TypedDicts 的打字问题。我想用“foo”方法定义一个抽象类,接受任何带有键“a”的字典。我想定义实现抽象类的具体类,并使用 foo 方法接受第一个类的“a”和“b”以及第二个类的“a”和“c”的字典。我实现了它,如下所示。但是 mypy 在这两种情况下都会返回以下错误
Argument 1 of "foo" is incompatible with supertype "AbstractClass"; supertype defines the argument type as "DictWithA"
我尝试了使用 TypeVar("T",bound=DictWithA) 或 Type[DictWithA] 的解决方法,但没有成功。
from abc import ABC
from typing import TypedDict
class DictWithA(TypedDict):
a: bool
class DictWithAandB(DictWithA):
b: int
class DictWithAandC(DictWithA):
c: int
class AbstractClass(ABC):
def foo(self, bar: DictWithA) -> int:
raise NotImplementedError()
class ConcreteClassB(AbstractClass):
def foo(self, bar: DictWithAandB) -> int:
return bar["b"] if bar["a"] else 0
class ConcreteClassC(AbstractClass):
def foo(self, bar: DictWithAandC) -> int:
return bar["c"] if bar["a"] else 2
阅读协变和逆变,但简而言之,
b = ConcreteClassB()
是一个AbstractClass
,因此b.foo
应该接受任何DictWithA
。但是,您的方法定义不接受任何 DictWithA
:将 da = DictWithA(0)
作为 b.foo(da)
传递将不起作用。这就是错误消息的含义。
在
class X:
def f(a : A, ...) -> ...:
...
class Y(X):
def f(a : B, ...) -> ...:
...
B
必须是 A
的超类。这与返回类型的工作方式相反。