将一个已构建的字典进行类型转换为 TypedDict。

4

我有一个像这样的东西(非常简化):

# mymodule.py

from typing import TypedDict, cast

D=TypedDict('D', {'x':int, 'y':int})
d = {}
d['x']=1
d['y']=2
d = cast(D, d)

但是我的mypy抱怨:

mymodule.py:9: error: 分配中存在不兼容的类型(表达式的类型为“D”,变量的类型为“Dict [str,int]”) 在1个文件(检查了1个源文件)中发现1个错误

将普通字典转换为TypedDict子类型是否有效?如果无效,那么正确的方式是如何“构建”一个字典,然后在之后声明其类型?

请注意,这很简化; 实际上,该字典是从比上面给出的更复杂的算法中构建的。

更新:即使我更改变量名称而不是尝试强制转换类型,问题似乎仍然存在。

# mymodule.py

from typing import TypedDict, cast

D=TypedDict('D', {'x':int, 'y':int})
d = {}
d['x']=1
d['y']=2
dd: D = d

错误:赋值时不兼容的类型(表达式的类型为“Dict [str,int]”,变量的类型为“D”)在1个文件中发现了1个错误(检查了1个源文件)


2
问题不在于转换,而在于将“d”用于两个不兼容的类型。 - MisterMiyagi
@MisterMiyagi 我明白了。您的意思是,一旦字典键已经固定,改变变量名称确实会被视为最佳实践? - Rick
@MisterMiyagi请稍等,我马上更新问题 - 如果我更改变量名称,mypy仍然会抱怨。 - Rick
@MisterMiyagi 哈哈!我找到了解决方案。我会发布一个答案。谢谢!!! - Rick
2个回答

5

在分配之前将初始字典进行类型转换:

from typing import TypeDict, cast

D = TypedDict('D', {'x':int, 'y':int})
d = cast(D, {})
d['x']=1
d['y']=2

这样可以确保变量d被直接推断为"a D"。否则,推断会立即将变量d锁定为Dict[..., ...],之后无法更改。


完美,正是我所需要的。 - Rick
1
@RicksupportsMonica,您可以直接使用“d”作为相应的“TypedDict”,甚至无需将其分配给另一个变量。这里的警告是类型检查器假定它是“D”即使在设置其项之前 - 因此它不会警告过早访问项目。当然,使用“d = {}”时,访问键时的错误是隐晦且不可靠的,但在某些情况下可能更可取。 - MisterMiyagi

1

当执行类型转换时,解决方案似乎是使用一个新的变量名:

# mymodule.py

from typing import TypedDict, cast

D=TypedDict('D', {'x':int, 'y':int})
d = {}
d['x']=1
d['y']=2
dd: D = cast(D, d)

我认为这强制使用新变量名称来表示键从此处不会再改变是最佳实践。对我来说有点过度,但我可以理解为什么一般情况下类型检查器以这种方式处理是有优势的。编辑:被接受的答案是更好的方法!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接