父对象的python类型提示字段

Posted

技术标签:

【中文标题】父对象的python类型提示字段【英文标题】:python type hint field of parent object 【发布时间】: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 我已经更新了问题,试图给出一个更现实的例子。 【参考方案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 有一个更好的解决方案..

以上是关于父对象的python类型提示字段的主要内容,如果未能解决你的问题,请参考以下文章

Python 类

Python 自动将dict-list嵌套数据 转换成 带类型定义的对象

Python学习:16.Python面对对象(反射,构造方法,静态字段,静态方法)

python3学习之类成员扩展父类方法的功能

《Python》 面向对象三大特性之多态封装

Python 多态