【发布时间】:2020-12-19 01:10:46
【问题描述】:
我们可以轻松地指定函数的返回类型,即使我们期望的类型作为它的参数之一提供:
from typing import TypeVar, Type, Union
T = TypeVar('T')
def to(t: Type[T], v) -> T:
return t(v)
s: str = to(str, 1)
i: int = to(str, 1) # Ok: Expected type 'int', got 'str' instead
但是如果我们提供 Union[str, int] 作为第一个参数,它就不起作用(不要在函数本身看到,我们可以用这个 Union 做一些更复杂的事情,即基于提供的 Union 构建 pydantic 模型)
G = Union[str, int]
g: G = to(G, 1) # Expected type 'Type[T]', got 'object' instead
那么如何指定函数的返回类型应该是作为第一个参数提供的类型呢?即使我们提供的不是纯类型如 int 或 str,还要 Union?
更新
更准确地说是我要装饰的功能
from typing import Type, Union
from pydantic import validate_arguments, BaseModel
def py_model(t, v: dict):
def fabric():
def f(x):
return x
f.__annotations__['x'] = t
return validate_arguments(f)
f = fabric()
return f(v)
class Model1(BaseModel): foo: int
class Model2(BaseModel): bar: str
print(repr(py_model(Union[Model1, Model2], {'foo':1}))) # Model1(foo=1)
print(repr(py_model(Union[Model1, Model2], {'bar':1}))) # Model2(bar='1')
所以当我调用 py_model(Union[Model1, Model2], ...) 我希望它会返回 Model1 或 Model2 之一,所以 Union[Model1, Model2]
【问题讨论】:
-
是的,因为
G不是类型。你认为Union[str, in](1)会如何工作? -
很明显,G 是通用别名,所以我想要一些魔术来提供通用别名并使函数返回一些实例,它对应于这个别名。即 Union[Model1, Model2], f 将根据提供的值构造模型 Model1 或 Model2 之一,所以我想指定函数的返回类型也是 Union[Model1, Model2]
-
没有魔法。你必须编写一个函数,用你需要的任何逻辑来真正做到这一点。
-
用函数更新帖子
-
@AntonOvsyannikov Juanpa 谈论的是构造 Generic 类型的函数,而不是使用
to的函数。我已经发布了一个可能满足您需求的答案。
标签: python generics types mypy pydantic