[英]Python type hinting: function return type, given as argument, but type is Generic Alias like Union
We can specify easily return type of function, even if type we expect is provided as one of it's argument:我们可以轻松指定函数的返回类型,即使我们期望的类型是作为参数之一提供的:
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
But it does not work if we provide Union[str, int] as first argument (do not see at function itself, we can do something more complex with this Union, ie construct pydantic model based on Union provided)但是如果我们提供 Union[str, int] 作为第一个参数,它就不起作用(不要看函数本身,我们可以用这个 Union 做一些更复杂的事情,即根据所提供的 Union 构建 pydantic 模型)
G = Union[str, int]
g: G = to(G, 1) # Expected type 'Type[T]', got 'object' instead
So how to specify that return type of function should be the one provided as first argument?那么如何指定函数的返回类型应该是作为第一个参数提供的类型? Even if we provide not pure type like int or str, but also Union?
即使我们提供的不是像 int 或 str 这样的纯类型,也可以提供 Union?
UPDATE更新
To be more precise there is the function i'd like to decorate更准确地说,有我想装饰的功能
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')
So when I call py_model(Union[Model1, Model2], ...) I expect it will return one of Model1 or Model2 so Union[Model1, Model2]所以当我调用 py_model(Union[Model1, Model2], ...) 我希望它会返回 Model1 或 Model2 之一所以 Union[Model1, Model2]
How about using a "Callable" for the to
function, instead of the operator to construct the type?如何为
to
函数使用“Callable”,而不是使用运算符来构造类型?
You could then have a constructor for Union type as argument.然后,您可以将 Union 类型的构造函数作为参数。
An example of such implementation would be:这种实现的一个例子是:
from typing import Any, Callable, TypeVar, Type, Union
T = TypeVar('T')
V = TypeVar('V')
def to(t: Callable[[V], T], v: V) -> T:
return t(v)
G = Union[str, int]
def build_g(v:G) -> G:
return v if isinstance(v, int) else str(v)
s: str = to(str, 1)
i1: int = to(int, 1)
i2: int = to(str, 1) # Ok: Expected type 'int', got 'str' instead
g1: G = to(build_g, 1) # No error raised
g2: G = to(build_g, "2") # No error raised
The code above only raises an error in mypy for i2
上面的代码仅在 mypy 中为
i2
引发错误
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.