Python 类型提示:函数 return 类型,作为参数给出,但类型是 Union 之类的通用别名
Python type hinting: function return type, given as argument, but type is Generic Alias like Union
我们可以轻松指定 return 函数类型,即使我们期望的类型作为其参数之一提供:
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
那么如何指定 return 类型的函数应该作为第一个参数提供?即使我们提供的不是像 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], ...) 我希望它将 return Model1 或 Model2 之一,所以 Union[Model1, Model2]
如何为 to
函数使用“可调用”而不是运算符来构造类型?
然后您可以将 Union 类型的构造函数作为参数。
此类实施的一个示例是:
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
上面的代码只在 i2
的 mypy 中引发错误
我们可以轻松指定 return 函数类型,即使我们期望的类型作为其参数之一提供:
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
那么如何指定 return 类型的函数应该作为第一个参数提供?即使我们提供的不是像 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], ...) 我希望它将 return Model1 或 Model2 之一,所以 Union[Model1, Model2]
如何为 to
函数使用“可调用”而不是运算符来构造类型?
然后您可以将 Union 类型的构造函数作为参数。
此类实施的一个示例是:
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
上面的代码只在 i2