Python: 将变量注释为 TypedDict 的键

Python: Annotate variable as key of a TypedDict

基本上是 this(尚未回答)问题的提炼版本。

我想声明一个变量应该只接受作为 TypedDict 中的键的值。

目前我正在定义一个单独的 Literal 类型来表示键,例如:

from typing import Literal, TypedDict


class MyTD(TypedDict):
    a: int
    b: int


mytd = MyTD(a=1, b=2)

key = "a"

mytd[key]  # error: TypedDict key must be a string literal; expected one of ('a', 'b')

MyTDKeyT = Literal["a", "b"]

typed_key: MyTDKeyT = "b"

mytd[typed_key]  # no error

我希望能够替换 Literal 定义,因为所有常见的原因都是希望尽量减少重复代码。

伪代码:

key: Keys[MyTD] = "a"
mytd[key]  # would be no error
not_key: Keys[MyTD] = "z"  # error

有办法实现吗?

澄清一下,鉴于 mypy 可以告诉我键类型需要是“a”或“b”的文字,我希望可能有一种不太容易出错的方法来注释变量类型,而不必并排维护两个单独的键列表,一次在 TypedDict 定义中,一次在 Literal 定义中。

使用 MyPy,我认为这是不可能的。我运行这个实验:

from typing import TypedDict

class MyTD(TypedDict):
    a: str
    b: int

d = MyTD(a='x', b=2)
reveal_type(list(d))

MyPy 输出为:

Revealed type is "builtins.list[builtins.str]"

这表明它在内部没有将键作为文字进行跟踪。否则,我们会期望:

Revealed type is "builtins.list[Literal['A', 'B']]" 

此外,这个错误在 MyPy 中出现,所以 __required_keys__ 甚至无法检查:

reveal_type(MyTD.__required_keys__)