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

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

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

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

result = {"Test": "something"}
result['key'] = {}
result['key']['sub_key'] = ["some string", "another string"]

此处的错误类似于:

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

如何防止此错误? 根据,建议做

result['key'] = {}  # type: ignore

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

问题

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

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

result = {"Test": "something"}

您没有声明您希望 result 的键和值具有什么类型,因此 MyPy 将自行解决。好吧,它说,我可以做到这一点——你只有字符串作为字典键,只有字符串作为字典值,因此 result 必须是 dict[str, str].

类型

然后我们进入第 2 行:

result['key'] = {}

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

没必要看第三行,因为基本上是一样的

如何解决这个问题?

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

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

    from typing import TypedDict
    
    class KeyDict(TypedDict, total=False):
        sub_key: list[str]
    
    
    class ResultDict(TypedDict, total=False):
        Test: str
        key: KeyDict
    
    
    result: ResultDict = {"Test": "something"}
    result['key'] = {}
    result['key']['sub_key'] = ["some string", "another string"]
    
  2. 你可以告诉 MyPy 这个字典中的 any 值可以是 str 类型,也可以是 [=25= 类型]:

    from typing import Union
    
    result: dict[str, Union[str, dict[str, list[str]]]] = {"Test": "something"}
    d: dict[str, list[str]] = {}
    d['sub_key'] = ["some string", "another string"]
    result['key'] = d
    
  3. 你可以告诉 MyPy 这个字典中的值可以是 任何东西(与关闭类型检查器没有什么不同):

    from typing import Any
    
    result: dict[str, Any] = {"Test": "something"}
    result['key'] = {}
    result['key']['sub_key'] = ["some string", "another string"]
    
  4. 您可以关闭类型检查器:

    result = {"Test": "something"}  
    result['key'] = {}  # type: ignore[assignment]
    result['key']['sub_key'] = ["some string", "another string"] # type: ignore[index]
    

无论如何,在不了解您的用例的情况下,很难知道什么是“最佳”解决方案。