[英]How do I declare return type based on argument type?
这个问题类似于Python Typing: declare return value type based on function argument但足够不同以至于它不适合注释。
我有以下功能:
T = TypeVar('T', dict, str)
def fun(t: T) -> T:
if t == dict:
return {"foo": "bar"}
else:
return "foo"
我希望能够这样称呼它:
a_string = fun(str)
a_dict = fun(dict)
Pylance 在第二行抛出这个错误:
Expression of type "dict[str, str]" cannot be assigned to return type "T@fun"
最后一行出现这个错误:
Expression of type "Literal['foo']" cannot be assigned to return type "T@fun"
根据这个答案,我应该能够做这样的事情:
T = TypeVar('T', dict, str)
def fun(t: Type[T]) -> T:
if t == dict:
return t({"foo": "bar"})
else:
return t("foo")
这会消除第二行的错误,但会导致最后一行出现不同的错误:
No overloads for "__init__" match the provided arguments
Argument types: (Literal['foo'])
我研究了这个答案很长时间才终于能够使它工作:
T = TypeVar('T', dict, str)
def fun(t: Callable[..., T]) -> T:
if t == dict:
return t({"foo": "bar"})
else:
return t("foo")
问题是我不明白它为什么有效。 我不明白为什么其他人不这样做。
问题是我不明白为什么它有效
最后一个有效,因为类型是可调用的。 所以这里的打字是说fun
需要一些东西,给定一些东西,会返回一个T
,你以类型的形式提供它。
我不明白为什么其他人不这样做。
第一个版本不起作用,因为->
的左侧和右侧之间没有绑定。 所以你可以传递一个类型变量,但你不能指定左边的特定必须是右边的特定。 换句话说,如果参数是一个dict
,那么根据签名,返回类型不一定是一个 dict ,而是仍然是 typevar 指定的类型(有点混乱,因为相同的符号- T
- 出现在两者中。但是, T
在这里表示“...之一”)。
第二个版本不起作用,因为就类型检查器而言, return
表明您也在返回一个类型。
你也可以在这里使用typing.overload
。
from typing import TypeVar, Type, overload, Callable
T = TypeVar('T')
@overload
def fun(t: Type[dict]) -> dict:
...
@overload
def fun(t: Type[str]) -> str:
...
def fun(t: Callable[..., T]) -> T
if t == dict:
return t({"foo": "bar"})
else:
return t("foo")
这应该允许fun(dict)
和fun(str)
,但不允许使用不同类型的调用,同时还确保fun
确实返回作为参数传递的类型的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.