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

Python如何实现类似TypeScript的索引访问类型 引用类字段类型做注解

解决方案

基础场景(对标TypeScript示例)

Python完全支持你想要的类似TypeScript索引访问类型的能力,和User["foo"]完全等效的写法就是User['foo'],不需要加typing.Type包裹。
你之前的写法报错是因为误用了typing.Type:Type[User]表示User类本身的类型,而非User实例的类型,自然无法拿到实例字段的类型。
修正后的可通过类型检查的代码如下:

from __future__ import annotations
import typing
import pydantic


class User(pydantic.BaseModel):
    foo: int


def f(foo: User['foo']):
    print(foo)


user = User(foo=42)
f(user.foo)

注意事项:在文件顶部加from __future__ import annotations是为了让类型注解延迟求值,运行时不会执行User['foo']的索引逻辑,避免非Pydantic类或者低版本Python运行时报错,类型检查器可以正常识别该注解。该写法目前对mypy、pyright等主流Python类型检查器均生效。

泛型场景

索引访问类型同样可以作用于泛型的TypeVar上,你标记??的位置直接按以下规则填写即可:

  • 要获取TResult.items的类型直接写TResult['items']
  • 要获取列表items的元素类型直接写TResult['items'][int]

修正后的完整代码如下:

from __future__ import annotations
import abc
from typing import TypeVar, Generic, Literal

from pydantic.generics import GenericModel

TResultItem = TypeVar("TResultItem")


class ResultBase(
    GenericModel, Generic[TResultItem]
):
    status: Literal["success", "failure"]
    items: list[TResultItem]


TResult = TypeVar("TResult", bound=ResultBase)


class CalculatorBase(Generic[TResult], abc.ABC):
    def calculate(self) -> TResult:
        try:
            items: TResult['items'] = []
            for i in range(10):
                items.append(
                    self._calculate_one(i)
                )
        except Exception:
            return self._create_result(
                "failure", []
            )
        else:
            return self._create_result(
                "success", items
            )

    @abc.abstractmethod
    def _calculate_one(self, i: int) -> TResult['items'][int]:
        ...

    @abc.abstractmethod
    def _create_result(
        self,
        status: Literal["success", "failure"],
        items: TResult['items'],
    ) -> TResult:  
        ...

如果你觉得取列表元素的写法不够直观,也可以调整泛型参数定义,把条目类型也作为CalculatorBase的泛型参数,写法兼容性更好也更易读:

TResultItem = TypeVar("TResultItem")
TResult = TypeVar("TResult", bound=ResultBase)


class CalculatorBase(Generic[TResult, TResultItem], abc.ABC):
    def calculate(self) -> TResult:
        try:
            items: list[TResultItem] = []
            # 其余逻辑不变
        # ...
    @abc.abstractmethod
    def _calculate_one(self, i: int) -> TResultItem:
        ...

    @abc.abstractmethod
    def _create_result(
        self,
        status: Literal["success", "failure"],
        items: list[TResultItem],
    ) -> TResult:  
        ...

内容的提问来源于stack exchange,提问作者peter554

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:06:06