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 认为您可能在这里犯了一个错误,并不意味着将该值添加到字典中。
没必要看第三行,因为基本上是一样的
如何解决这个问题?
有几种方法可以解决这个问题。按照最喜欢(尽可能使用)到最不喜欢(仅作为最后手段使用)的顺序:
您可以通过将其注释为 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"]
你可以告诉 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
你可以告诉 MyPy 这个字典中的值可以是 任何东西(与关闭类型检查器没有什么不同):
from typing import Any
result: dict[str, Any] = {"Test": "something"}
result['key'] = {}
result['key']['sub_key'] = ["some string", "another string"]
您可以关闭类型检查器:
result = {"Test": "something"}
result['key'] = {} # type: ignore[assignment]
result['key']['sub_key'] = ["some string", "another string"] # type: ignore[index]
无论如何,在不了解您的用例的情况下,很难知道什么是“最佳”解决方案。
我试图在现有字典的第二层实例化一个空字典,然后为其分配一个键值对,但 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 认为您可能在这里犯了一个错误,并不意味着将该值添加到字典中。
没必要看第三行,因为基本上是一样的
如何解决这个问题?
有几种方法可以解决这个问题。按照最喜欢(尽可能使用)到最不喜欢(仅作为最后手段使用)的顺序:
您可以通过将其注释为
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"]
你可以告诉 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
你可以告诉 MyPy 这个字典中的值可以是 任何东西(与关闭类型检查器没有什么不同):
from typing import Any result: dict[str, Any] = {"Test": "something"} result['key'] = {} result['key']['sub_key'] = ["some string", "another string"]
您可以关闭类型检查器:
result = {"Test": "something"} result['key'] = {} # type: ignore[assignment] result['key']['sub_key'] = ["some string", "another string"] # type: ignore[index]
无论如何,在不了解您的用例的情况下,很难知道什么是“最佳”解决方案。