使用 Python 类型注释声明通用 Mapping 子类?

Declare a generic Mapping subclass with Python type annotations?

我正在尝试将泛型类型注释添加到 Python 3.4 中的 Mapping 子类:

from typing import Mapping, TypeVar, Iterator, Dict

K = TypeVar('K')
V = TypeVar('V')


class M(Mapping[K, V]):
    def __init__(self) -> None:
        self.d = dict()     # type: Dict[K, V]

    def __getitem__(self, item: K) -> V:
        return self.d[item]

    def __len__(self) -> int:
        return len(self.d)

    def __iter__(self) -> Iterator[K]:
        return iter(self.d)


# Also errors, but less
# d = dict()  # type: Mapping[K, V]

我哪里做错了,为什么 mypy 没有给出更有用的错误信息?

$ python -V; mypy -V
Python 3.4.3+
mypy 0.470

$ mypy map.py
map.py:7: error: Invalid type "map.K"
map.py:7: error: Invalid type "map.V"
map.py:9: error: Invalid type "map.K"
map.py:9: error: Invalid type "map.V"

看来您必须添加 Generic[K, V] 作为显式基础 class。

from typing import Mapping, TypeVar, Iterator, Dict, Generic

K = TypeVar('K')
V = TypeVar('V')


class M(Generic[K, V], Mapping[K, V]):
    def __init__(self) -> None:
        self.d = dict()     # type: Dict[K, V]

    def __getitem__(self, item: K) -> V:
        return self.d[item]

    def __len__(self) -> int:
        return len(self.d)

    def __iter__(self) -> Iterator[K]:
        return iter(self.d)

在你问之前,mypy 没有 Hashable 键约束的功能概念(从版本 0.470 开始)。 [1] [2]