带有键/值类型对的类型提示字典

zna*_*f94 5 python dictionary type-hinting python-3.x

是否可以使用 Python 类型提示将字典的键和值的类型指定为对?

例如 :

  • 如果键是 an int,则值应该是 astr
  • 如果 key 是 a str,value 应该是 anint

如果我写:

Dict[Union[int, str], Union[int, str]]
Run Code Online (Sandbox Code Playgroud)

它允许str -> strint -> int,这是不允许的。

与 :

Union[Dict[int, str], Dict[str, int]]
Run Code Online (Sandbox Code Playgroud)

字典可以是aDict[int, str]Dict[str, int]但不能同时是两者......

我也研究过TypedDict,但它需要明确给出所有密钥。

Lyl*_*ham 3

如果typing.cast您的应用程序可以接受 using ,那么可以通过创建一个Dict具有覆盖__setitem__和 的子类的类__getitem__,并将您的字典转换为该类型来完成。从那时起,类型检查器将推断出正确的KeyType: ValueType对。

这种方法的注意事项是,您不能使用它来类型检查正确的字典构造,因为这发生在强制转换之前。此外,您需要为 、 等内容添加更多重写update__iter__可能还需要添加其他 dict 方法,以对__setitem__/ __getitem__dict 访问之外的内容进行类型检查。

例子:

from typing import Dict, overload, cast


class KVTypePairedDict(Dict):
    @overload
    def __getitem__(self, key: str) -> int: ...
    @overload
    def __getitem__(self, key: int) -> str: ...
    def __getitem__(self, key): ...

    @overload
    def __setitem__(self, key: str, value: int) -> None: ...
    @overload
    def __setitem__(self, key: int, value: str) -> None: ...
    def __setitem__(self, key, value): ...


test: KVTypePairedDict = cast(KVTypePairedDict, {"foo": 0, 1: "bar"})

# str keys
a: int = test["foo"]
test["foo"] = 0
c: str = test["foo"]  # <-- mypy and PyCharm flag this
test["foo"] = "bar"  # <-- mypy and PyCharm flag this

# int keys
d: str = test[1]
test[1] = "bar"
b: int = test[0]  # <-- mypy and PyCharm flag this
test[1] = 0  # <-- mypy and PyCharm flag this
Run Code Online (Sandbox Code Playgroud)