如何正确地对 dict 进行子类型化,以便 MyPy 将其识别为通用的?

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

我有一个字典的子类:

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
,但都无济于事。

python mypy python-typing
1个回答
0
投票

作为一般规则,您可以记住始终为泛型类型提供类型参数,无论上下文如何。 (记住:显式优于隐式。)

这意味着在注释中(例如

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.

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