我有一个字典的子类:
class MyDict(dict):
pass
后面我用定义:
my_var: MyDict[str, int] = {'a': 1, 'b': 2}
MyPy 抱怨:
error: "MyDict" expects no type arguments, but 2 given [type-arg]
如何定义 MyDict 以便 MyPy 将其识别为具有两个类型参数的泛型?
我试过从
typing.Dict
派生并添加协议MutableMapping
,但都无济于事。
作为一般规则,您可以记住始终为泛型类型提供类型参数,无论上下文如何。 (记住:显式优于隐式。)
这意味着在注释中(例如
d: dict[str, int]
)和在子类化时(例如class MyDict(dict[str, int]): ...
)。
如果你想在你自己的子类中保留基类的部分或所有类型参数的泛型,那么传递类型变量代替特定类型参数:
from collections.abc import Hashable
from typing import TypeVar
K = TypeVar("K", bound=Hashable)
V = TypeVar("V")
class MyDict(dict[K, V]):
...
class MyStrKeyDict(dict[str, V]):
...
class MyIntValDict(dict[K, int]):
...
x: MyDict[str, int]
y: MyStrKeyDict[int]
z: MyIntValDict[str]
MyPy 告诉您它不期望
MyDict
的任何类型参数的原因是它隐含地假定 MyDict
是 dict[Any, Any]
的子类,因为您没有指定类型参数。
旁注:现在分配例如仍然是错误的
x = {"a": 1}
就像您在示例中所做的那样,因为 dict
不是 MyDict
的子类型。这就是为什么通常最好将 ABC 子类化(在本例中为Mapping
或 MutableMapping
)或使用 protocols.