如何根据参数类型声明 return 类型?
How do I declare return type based on argument type?
此问题与 类似,但差异很大,不适合发表评论。
我有以下功能:
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")
问题是我不明白为什么它有效。而且我不明白为什么其他人不这样做。
The problem with this is I don't understand why it works
最后一个有效,因为类型 是 可调用的。所以这里的输入表示 fun
需要一些东西,给定一些东西,将 return 变成 T
,然后你以类型的形式提供它。
And I don't understand why the others don't.
第一个版本不起作用,因为 ->
的左侧和右侧之间没有绑定。所以你可以传递一个typevar,但是你不能指定左边的specific一定是右边的specific。换句话说,如果参数是 dict
,那么根据签名,return 类型不一定是字典,而仍然是 typevar 指定的类型(它是有点混乱,因为相同的符号 - T
- 出现在两者中。但是,T
在这里表示“...之一”)。
第二个版本不起作用,因为 return
表明您也在 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
的确 return 的值作为参数传递的类型。
此问题与
我有以下功能:
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")
问题是我不明白为什么它有效。而且我不明白为什么其他人不这样做。
The problem with this is I don't understand why it works
最后一个有效,因为类型 是 可调用的。所以这里的输入表示 fun
需要一些东西,给定一些东西,将 return 变成 T
,然后你以类型的形式提供它。
And I don't understand why the others don't.
第一个版本不起作用,因为 ->
的左侧和右侧之间没有绑定。所以你可以传递一个typevar,但是你不能指定左边的specific一定是右边的specific。换句话说,如果参数是 dict
,那么根据签名,return 类型不一定是字典,而仍然是 typevar 指定的类型(它是有点混乱,因为相同的符号 - T
- 出现在两者中。但是,T
在这里表示“...之一”)。
第二个版本不起作用,因为 return
表明您也在 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
的确 return 的值作为参数传递的类型。