mypy 错误:赋值中的类型不兼容(表达式的类型为“Dict[<nothing>, <nothing>]”,目标的类型为“List[str]”)

And*_* L. 6 python type-hinting mypy python-typing

我尝试在现有字典的第二层实例化一个空字典,然后为其分配一个键值对,但 MyPy 抛出错误。

这是一个最小的示例,当激活 MyPy 检查时它将重现它:

result = {"Test": "something"}
result['key'] = {}
result['key']['sub_key'] = ["some string", "another string"]
Run Code Online (Sandbox Code Playgroud)

这里的错误将类似于:

mypy(error): Incompatible types in assignment (expression has type
"Dict[<nothing>, <nothing>]", target has type "List[str]")
Run Code Online (Sandbox Code Playgroud)

我该如何防止这个错误?根据类似的问题,建议这样做

result['key'] = {}  # type: ignore
Run Code Online (Sandbox Code Playgroud)

作为一种解决方法,但这似乎不是很优雅,这就是为什么我想知道是否还有更多的事情可以做。

Ale*_*ood 22

问题

\n

好的,让我们看看这里的前两行。

\n

首先,定义你的字典result。你这样定义它:

\n
result = {"Test": "something"}\n
Run Code Online (Sandbox Code Playgroud)\n

您没有声明您期望键和值result具有什么类型,因此 MyPy 需要自行解决。好吧,它说,我可以这样做 \xe2\x80\x94 你只有字符串作为字典键,并且只有字符串作为字典值,因此result必须是类型dict[str, str]

\n

然后我们进入第 2 行:

\n
result['key'] = {}\n
Run Code Online (Sandbox Code Playgroud)\n

MyPy 很合理地引发了错误。“嘿嘿,这看起来像是一个错误!” 它说。到目前为止,您仅将字符串作为字典值,并且您还没有明确告诉 MyPy 该字典中可以包含非值str,因此 MyPy 认为您可能在这里犯了错误,并且没有意思是将该值添加到字典中。

\n

没有必要看第三行,因为它基本上是同样的事情

\n

如何解决这个问题?

\n

有几种方法可以解决这个问题。按照最首选(如果可能的话使用)到最不首选(仅作为最后手段使用)的顺序:

\n
    \n
  1. 您可以通过将其注释为 .MyPy 来告诉 MyPy该特定字典具有与某些字符串键关联的某些类型TypedDict。(但是,您必须将"sub-key"密钥更改为"sub_key",因为“子密钥”不是有效的变量名称。)

    \n
    from typing import TypedDict\n\nclass KeyDict(TypedDict, total=False):\n    sub_key: list[str]\n\n\nclass ResultDict(TypedDict, total=False):\n    Test: str\n    key: KeyDict\n\n\nresult: ResultDict = {"Test": "something"}\nresult['key'] = {}\nresult['key']['sub_key'] = ["some string", "another string"]\n
    Run Code Online (Sandbox Code Playgroud)\n
  2. \n
  3. 您可以告诉 MyPy该字典中的任何值都可以是 type str,也可以是 type dict[str, list[str]]

    \n
    from typing import Union\n\nresult: dict[str, Union[str, dict[str, list[str]]]] = {"Test": "something"}\nd: dict[str, list[str]] = {}\nd['sub_key'] = ["some string", "another string"]\nresult['key'] = d\n
    Run Code Online (Sandbox Code Playgroud)\n
  4. \n
  5. 您可以告诉 MyPy 该字典中的值可以是任何值(与关闭类型检查器没有什么不同):

    \n
    from typing import Any\n\nresult: dict[str, Any] = {"Test": "something"}\nresult['key'] = {}\nresult['key']['sub_key'] = ["some string", "another string"]\n
    Run Code Online (Sandbox Code Playgroud)\n
  6. \n
  7. 您可以关闭类型检查器:

    \n
    result = {"Test": "something"}  \nresult['key'] = {}  # type: ignore[assignment]\nresult['key']['sub_key'] = ["some string", "another string"] # type: ignore[index]\n
    Run Code Online (Sandbox Code Playgroud)\n
  8. \n
\n

无论如何,如果不了解更多有关您的用例的信息,就很难知道“最佳”解决方案是什么。

\n