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

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

我正在尝试向 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"
python generics python-typing mypy
1个回答
8
投票

似乎您必须添加

Generic[_K, _V]
作为显式基类。

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[_K, _V] = dict()

    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]

注意:建议将您的

TypeVar
命名为前导
_
,以将其标记为私有。它不应该在你的包之外导入和使用

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