Python类型提示:函数返回类型,以参数形式给出,但类型是通用别名(如Union) [英] Python type hinting: function return type, given as argument, but type is Generic Alias like Union

查看:286
本文介绍了Python类型提示:函数返回类型,以参数形式给出,但类型是通用别名(如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

但是如果我们提供Union [str,int]作为第一个参数是行不通的(看不到函数本身,我们可以对此Union做一些更复杂的事情,即基于所提供的Union构建pydantic模型)

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, i.e. construct pydantic model based on Union provided)

G = Union[str, int]
g: G = to(G, 1) # Expected type 'Type[T]', got 'object' instead 

那么如何指定函数的返回类型应该是作为第一个参数提供的呢?即使我们提供的不是int或str这样的纯类型,也可以提供Union吗?

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?

更新

更准确地说,是我想装饰的功能

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')

因此,当我调用py_model(Union [Model1,Model2],...)时,我希望它会返回Model1或Model2中的一个,因此会返回Union [Model1,Model2]

So when I call py_model(Union[Model1, Model2], ...) I expect it will return one of Model1 or Model2 so Union[Model1, Model2]

推荐答案

如何使用"Callable" to函数,而不是运算符来构造类型?

How about using a "Callable" for the to function, instead of the operator to construct the type?

然后您可以将Union类型的构造函数用作参数.

You could then have a constructor for Union type as argument.

这种实现的一个例子是:

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

上面的代码仅在i2

这篇关于Python类型提示:函数返回类型,以参数形式给出,但类型是通用别名(如Union)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆