为什么TypedDict中不能将Final字典用作文字字典?

6
我正在尝试实现以下内容(请参见mypy playground):链接
from typing import TypedDict, Final

account_schema: Final = {"name": str, "email": str}

Account = TypedDict("Account", account_schema)
AccountPatch = TypedDict("AccountPatch", account_schema, total=False)

我的想法是可以在一个地方指定模式,其中一个版本需要所有字段 (Account, 插入数据库时),另一个版本使所有字段可选 (AccountPatch, 更新数据库时)。

来自PEP 586

Final限定符作为一种简写方式,用于声明变量实际上是Literal

但是 mypy 报错:

error: TypedDict() expects a dictionary literal as the second argument

TypedDict为什么不允许将Final字典作为其第二个参数?

针对我的核心问题,是否有办法在不必复制架构的情况下,同时为两个TypedDict(一个具有完整性,另一个没有完整性)使用相同的模式?


@MisterMiyagi 那么,我的理解是account_schema实际上是Literal,但它不符合TypedDict构造函数的定义,对吗? - Mario Ishac
2
这不是关于“TypedDict”的运行时构造函数,而是关于静态类型的含义。在错误显示的上下文中,没有涉及构造函数 - 一切都是由静态分析器完成的。这些需要一个字典字面量,例如{1:2,3:4}Literal类型恰好被命名类似并不重要;这不是常见类型检查器可以处理的内容。 - MisterMiyagi
@MisterMiyagi 我明白了,感谢您的澄清。现在我想要更多的意见而不是具体答案,但是考虑到我无法提前指定字典文字以去重模式,您认为代码生成是否是这里要采取的路线? - Mario Ishac
但是您回答了我的问题,如果您愿意发表有关字面值 vs Literal 的答案,我将接受它。 - Mario Ishac
1
如果有人感兴趣,错误是在这里引发的 https://github.com/python/mypy/blob/990b6a6f03ad82c10cb8edbe70508b943336f7f3/mypy/semanal_typeddict.py#L242-L244 - Sebastian Kreft
显示剩余2条评论
1个回答

1
正如评论中指出的那样,这是不可能的。请参见在mypy的github上引发的问题:TypedDict keys reuse?。错误是在这里引发的。
唯一定义两个TypeDict的方法是重复代码。
from typing import TypedDict

Account = TypedDict("Account", {"name": str, "email": str})
AccountPatch = TypedDict("AccountPatch", {"name": str, "email": str}, total=False)

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