【发布时间】: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