Python打字:根据函数参数声明返回值类型

时间:2020-02-13 07:39:31

标签: python python-3.x typing

假设我有一个将类型作为参数并返回该类型实例的函数:

test.subtest.all

然后我可以调用它并获取提供的类型的对象:

{% for subtest in test.subtest.all %}
    <li>
        <div class="checkbox-group">
            <input type="checkbox" id="aUniqueName" name="{{ subtest.name }}" value="example"/>
            <label for="aUniqueName">{{subtest.name}}</label>
        </div>
    </li>
{% endfor %}

该列表并不详尽,我希望能够在适当的构造函数中使用任何类型。

然后,我想为该函数添加类型提示。该函数的返回值的类型提示应该是什么?


我尝试过using simply t,因为def fun(t): return t(42) 是一种类型:

fun(int)           # 42
fun(float)         # 42.0
fun(complex)       # (42+0j)
fun(str)           # "42"
fun(MyCustomType)  # something

但这不起作用:

main.py:1:错误:未定义名称't'


This answer建议using a TypeVar

t

但这似乎不对,因为def fun(t: type) -> t: return t(42) 表示一个类型,因此它建议返回类型本身,而不是其实例。 Mypy拒绝了它:

main.py:6:错误:“对象”不可调用


Using Any显然有效,但是我觉得它太模糊了,没有传达意图:

from typing import TypeVar

T = TypeVar("T")

def fun(t: T) -> T:
    return t(42)

2 个答案:

答案 0 :(得分:4)

您正在寻找typing.Type,因此具有以下作用:

from typing import TypeVar, Type

T = TypeVar("T", str, complex, float, int)

def fun(t: Type[T]) -> T:
    return t(42)

fun(int)
fun(float)
fun(complex)
fun(str)

请注意,您的类型变量需要受到约束,因为并非所有Type对象都接受参数,但是您可以将其约束为一些与您的示例类似的对象。

答案 1 :(得分:4)

TLDR:您需要TypeVar来实现呼叫的返回类型 t

def fun(t: Callable[[int], R]) -> R:
    ...

在这里,对类型的限制过于严格。该函数接受任何采用整数的Callable,并且该函数的返回类型为Callable的返回类型。可以使用TypeVar来指定返回类型:

from typing import Callable, TypeVar


R = TypeVar('R')  # the variable return type


def fun(t: Callable[[int], R]) -> R:
    return t(42)

fun(int)                            # Revealed type is 'builtins.int*'
fun(float)                          # Revealed type is 'builtins.float*'
reveal_type(fun(lambda x: str(x)))  # Revealed type is 'builtins.str*'

这同样适用于类型,因为类型实例化是一个调用。

如果签名比较复杂,例如需要带有关键字参数的参数,请使用Protocol(来自typingtyping_extensions)。


请注意,如果明确希望仅将42传递给Callable,则Literal(来自typingtyping_extensions)可以用来指定

R = TypeVar('R')


def fun(t: Callable[[Literal[42]], R]) -> R:
    return t(42)

请注意,Callable[[int], R]类型的任何函数也都满足Callable[[Literal[42]], R]

相关问题