【问题标题】:python type hint field of parent object父对象的python类型提示字段
【发布时间】:2022-01-01 02:57:28
【问题描述】:

鉴于下面的类User,有没有办法在函数f 中键入提示字段User.foo 的类型(没有明确的硬编码int)?有时在更复杂的情况下,我希望能够直接引用从父类型派生的父对象字段的类型。用 Python 可以吗?

import typing

import pydantic


class User(pydantic.BaseModel):
    foo: int


# what type annotation to use for type of User.foo?
# some things i've tried:
#   User.foo
#   typing.Type[User.foo]
#   typing.Type[User].foo
#   typing.Type[User]["foo"]
def f(foo: typing.Type[User].foo):
    print(foo)


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

到目前为止,无论我尝试什么,在运行 mypy 或运行 python 时总是会出错。


更新。我认为我上面给出的例子太简单了,无法真正描述问题。下面的例子更现实一些。有一些 ”??”标记了我想进行类型注释的位置(类似于Type[TResult.items]),但找不到解决方案。

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 = []  # 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):  # -> ??
        ...

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


更新。这是一些打字稿,我基本上是在寻找 python 等价物,如果它存在的话。

type User = {
    foo: number;
}

function f(foo: User["foo"]) {
    console.log(foo)
}

const user: User = {foo: 42}
f(user.foo)

【问题讨论】:

  • User.foo 不是int 的类型;它是一个属性,可以采用int 类型的
  • > User.foo 不是 int 类型;这是一个可以采用 int 类型值的属性是的,我同意 User.foo 本身是错误的。我只是想知道这个概念是否有 一些符号......
  • 不能说我喜欢依赖父类型来键入参数,因为无论如何都会依赖它作为int 来编写函数。你有什么复杂的类型需要这个?
  • @StevenSummers 我已经更新了问题,试图给出一个更现实的例子。

标签: python type-hinting mypy typing pydantic


【解决方案1】:

您可以使用变量将类型从对象中抽象出来:

import pydantic

foo_type = int  # holds type of User.foo


class User(pydantic.BaseModel):
    foo: foo_type


def f(foo: foo_type):
    print(foo)


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

打印:

42

您也可以使用User的对象自动获取类型:

foo_type = type(User(foo=0).foo)

【讨论】:

  • 嗯,没错。我想总比没有好,虽然我希望 python 有一个更好的解决方案..
猜你喜欢
  • 2023-03-22
  • 1970-01-01
  • 2018-06-25
  • 2017-11-21
  • 2020-06-06
  • 2022-06-12
  • 2022-11-18
  • 2017-07-05
  • 2021-09-28
相关资源
最近更新 更多