如何在类中利用泛型TypedDict实现类型提示与点语法补全?
问题:能否在泛型类中获取传入的TypedDict类型信息,实现点访问的类型提示?
我希望在__getattr__方法中,从传入的泛型TypedDict获取类型注解,让使用点符号访问属性时能获得代码补全与语法高亮,请问这是否可行?示例代码如下:
from typing import TypedDict class MyDict[T](dict): def __init__(self, base_dict: T) -> None: super().__init__() self._data = base_dict def __getattr__(self, item): dots = item.split(".") data = self._data for dot in dots: data = data.get(dot) if isinstance(data, dict): return MyDict(data) if data is None: raise ValueError("Key not found") return data class TestDef(TypedDict): foo: int bar: str baz: dict[str, bool] data_dict: TestDef = { "foo": 10, "bar": "bar", "baz": {"qux": True} } d = MyDict(data_dict) v1 = d.foo print(v1) v2 = d.baz.qux print(v2)
解答
这是可行的,只需调整类型注解逻辑,让Pyright、Mypy这类类型检查器能识别泛型参数对应的TypedDict结构,从而提供代码补全和类型提示。
关键修改方案
- 用
TypeVar绑定TypedDict类型,明确泛型参数的约束范围 - 给
__getattr__添加返回类型注解,映射TypedDict的键与对应值的类型 - 针对嵌套字典场景,为子结构定义对应的TypedDict,实现多层级的类型提示
修改后的代码示例:
from typing import TypedDict, TypeVar, cast # 定义绑定TypedDict的泛型变量 T = TypeVar("T", bound=TypedDict) NestedT = TypeVar("NestedT", bound=TypedDict) class MyDict[T](dict): def __init__(self, base_dict: T) -> None: super().__init__() self._data = base_dict def __getattr__(self, item: str): dots = item.split(".") data = self._data for dot in dots: if not isinstance(data, dict): raise ValueError("无法在非字典类型上访问嵌套键") data = data.get(dot) if data is None: raise ValueError(f"未找到键: '{dot}'") # 嵌套字典返回带对应类型的MyDict实例 if isinstance(data, dict): return cast(MyDict[NestedT], MyDict(data)) # 基于TypedDict的注解返回对应类型 return cast[T.__annotations__[item], type(data)](data) # 定义嵌套结构的TypedDict,实现精确类型提示 class BazDef(TypedDict): qux: bool class TestDef(TypedDict): foo: int bar: str baz: BazDef data_dict: TestDef = { "foo": 10, "bar": "bar", "baz": {"qux": True} } d = MyDict(data_dict) v1 = d.foo # 编辑器会提示类型为int v2 = d.baz.qux # 编辑器会提示类型为bool
补充说明
- 嵌套结构的类型提示依赖子结构的TypedDict定义,这样类型检查器能准确识别多层级属性的类型
cast仅用于辅助类型推断,不会影响代码运行时逻辑- 运行时的
__getattr__逻辑保持原有的键查找逻辑,类型注解仅服务于编辑器和类型检查工具
内容的提问来源于stack exchange,提问作者Jerakin
相关产品推荐
相关产品推荐

