Mypy:我应该如何输入一个以字符串为键且值可以是字符串或字符串列表的字典?

jje*_*jei 14 python python-3.x mypy

我正在使用 Python 3.8.1 和 mypy 0.782。我不明白为什么 mypy 会抱怨以下代码:

from typing import Union, List, Dict
Mytype = Union[Dict[str, str], Dict[str, List[str]]]
s: Mytype = {"x": "y", "a": ["b"]}
Run Code Online (Sandbox Code Playgroud)

Mypy 在第 3 行给出以下错误:

Incompatible types in assignment (expression has type "Dict[str, Sequence[str]]", variable has type "Union[Dict[str, str], Dict[str, List[str]]]")
Run Code Online (Sandbox Code Playgroud)

如果我将最后一行更改为s: Mytype = {"a": ["b"]}mypy 不会抱怨。但是,当再添加一行时s["a"].append("c")会导致错误:

error: Item "str" of "Union[str, List[str]]" has no attribute "append"
Run Code Online (Sandbox Code Playgroud)

上述情况该如何解释呢?我应该如何输入一个以字符串为键且值可以是字符串或字符串列表的字典?

发现这个: https: //github.com/python/mypy/issues/2984#issuecomment-285716826但仍然不完全确定为什么会发生上述情况以及我应该如何修复它。

编辑: 虽然还不清楚为什么建议的修改Mytype = Dict[str, Union[str, List[str]]]不能解决错误,但s['a'].append('c')我认为评论中以及/sf/answers/4400342061/中建议的 TypeDict 方法是可行的方法,所以将该方法标记为解决方案。

请参阅类似的问题:Indicating multiple value in a Dict[] for typehins,Georgy 在评论中建议。

ale*_*ame 16

因为不能同时s: Mytype有类型Dict[str, str]和类型。Dict[str, List[str]]你可以像这样做你想做的事:

Mytype = Dict[str, Union[str, List[str]]]
Run Code Online (Sandbox Code Playgroud)

但也许有问题,因为Dict是不变的


您也可以使用TypedDict,但只需要一组固定的字符串键:

from typing import List, TypedDict

MyType = TypedDict('MyType', {'x': str, 'a': List[str]})
s: MyType = {"x": "y", "a": ["b"]}

s['a'].append('c')
Run Code Online (Sandbox Code Playgroud)

笔记:

除非您使用的是 Python 3.8 或更高版本(TypedDict在标准库打字模块中可用),否则您需要使用 pip 安装 Typing_extensions 才能使用 TypedDict


当然,您可以使用Any

Mytype = Dict[str, Any]
Run Code Online (Sandbox Code Playgroud)

  • @jjei `Union[Dict[str, str], Dict[str, List[str]]]` 与 `Dict[str, Union[str, List[str]]]` 不同。在第一种情况下,您只能使用 str 值的字典或将字符串列表作为值的字典,但不能使用混合类型的值。 (4认同)