假设我有一个将类型作为参数并返回该类型实例的函数:
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'
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)
答案 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
(来自typing
或typing_extensions
)。
请注意,如果明确希望仅将42
传递给Callable
,则Literal
(来自typing
或typing_extensions
)可以用来指定
R = TypeVar('R')
def fun(t: Callable[[Literal[42]], R]) -> R:
return t(42)
请注意,Callable[[int], R]
类型的任何函数也都满足Callable[[Literal[42]], R]
。