You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在类中利用泛型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结构,从而提供代码补全和类型提示。

关键修改方案

  1. 用TypeVar绑定TypedDict类型,明确泛型参数的约束范围
  2. 给__getattr__添加返回类型注解,映射TypedDict的键与对应值的类型
  3. 针对嵌套字典场景,为子结构定义对应的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 05:42:34