繁体   English   中英

如何根据参数类型声明返回类型?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM