Mypy:定义对 TypedDict 的每个子级起作用的函数

问题描述 投票:0回答:1

我有一个关于 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
python mypy python-typing typeddict
1个回答
0
投票

阅读协变和逆变,但简而言之,

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
的超类。这与返回类型的工作方式相反。

© www.soinside.com 2019 - 2024. All rights reserved.