简体   繁体   English

如何处理“不兼容的返回值类型(得到重载函数)”问题

[英]How to deal with "Incompatible return value type (got overloaded function)" issue

I'm trying to define a function which returns another function.我正在尝试定义一个返回另一个函数的函数。 The function it returns is overloaded.它返回的函数是重载的。

For example:例如:

from typing import overload, Union, Callable

@overload
def foo(a: str) -> str:
    pass
@overload
def foo(a: int) -> int:
    pass
def foo(a: Union[str, int]) -> Union[str, int]:
    if isinstance(a, int):
        return 1
    else:
        # str
        return "one"

def bar() -> Callable[[Union[str, int]], Union[str, int]]:
    return foo # Incompatible return value type (got overloaded function, expected "Callable[[Union[str, int]], Union[str, int]]")

However, my typing for the function bar is coming up as an error using Mypy.但是,我在功能bar输入是使用 Mypy 时出现的错误。

How do I type bar correctly?如何正确键入bar What am I doing wrong?我究竟做错了什么?

The issue here is partly that the Callable type is a little too limited to accurately express the type for foo and also partly that mypy is currently very conservative when analyzing the compatibility of overloads against Callables.这里的问题部分在于Callable类型有点过于受限,无法准确表达foo的类型,部分在于 mypy 目前在分析与 Callables 重载的兼容性时非常保守。 (It's hard to do in the general case). (在一般情况下很难做到)。

Probably the best approach for now is to just define a more precise return type by using Callback protocol and return that instead:目前最好的方法可能是通过使用回调协议定义更精确的返回类型并返回它:

For example:例如:

from typing import overload, Union, Callable

# Or if you're using Python 3.8+, just 'from typing import Protocol'
from typing_extensions import Protocol

# A callback protocol encoding the exact signature you want to return
class FooLike(Protocol):
    @overload
    def __call__(self, a: str) -> str: ...
    @overload
    def __call__(self, a: int) -> int: ...
    def __call__(self, a: Union[str, int]) -> Union[str, int]: ...


@overload
def foo(a: str) -> str:
    pass
@overload
def foo(a: int) -> int:
    pass
def foo(a: Union[str, int]) -> Union[str, int]:
    if isinstance(a, int):
        return 1
    else:
        # str
        return "one"

def bar() -> FooLike:
    return foo  # now type-checks

Note: Protocol was added to the typing module as of Python 3.8.注意:从 Python 3.8 开始, Protocol已添加到typing模块中。 If you want it in earlier versions of Python, install the typing_extensions module ( pip install typing_extensions`) and import it from there.如果您希望在早期版本的 Python 中使用它,请安装typing_extensions module ( pip install typing_extensions`)并从那里导入它。

Having to copy the signature like this twice is admittedly a bit clunky.不得不像这样复制签名两次无疑有点笨拙。 People generally seem to agree that this is a problem (there are various issues about this in the typing and mypy issue trackers), but I don't think there's any consensus on how to best solve this yet.人们似乎普遍同意这是一个问题(在打字mypy问题跟踪器中有各种关于此的问题),但我认为对于如何最好地解决这个问题还没有达成任何共识。

I sorted that out by changing to pyre:我通过更改为 pyre 来解决这个问题:

from typing import overload, Union

def foo(a: Union[str, int]) -> Union[str, int]:
    if isinstance(a, int):
        return 1
    else:
        return 'a string'

check:查看:

    (.penv) nick$: pyre check
     ƛ No type errors found

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 mypy 抱怨:带有 Type[TypeVar['T', str, date]] 和 T 输出的函数类型注释:不兼容的返回值类型(得到“str”,预期为“date”) - mypy complains: function type annotation with Type[TypeVar['T', str, date]] and T output: Incompatible return value type (got "str", expected "date") 当 function 只能返回 str 时,mypy 抱怨返回值类型不兼容(得到“可选 [str]”,预期为“str”) - mypy complains Incompatible return value type (got “Optional[str]”, expected “str”) when a function can only return str mypy:不兼容的返回值类型 - mypy: Incompatible return value type mypy 错误:返回值类型不兼容(得到“object”,预期为“Dict[Any, Any]”) - mypy error: Incompatible return value type (got "object", expected "Dict[Any, Any]") 错误:返回值类型不兼容(得到“Tuple[Tuple[float, float], ...]”,预期为“List[Any]”) - error: Incompatible return value type (got "Tuple[Tuple[float, float], ...]", expected "List[Any]") mypy 错误:返回值类型不兼容(得到“Union[bool_, ndarray]”,预期为“bool”) - mypy error: Incompatible return value type (got "Union[bool_, ndarray]", expected "bool") mypy 数值类型的返回值类型不兼容 - mypy Incompatible return value type for numeric types 如何处理“不兼容类型”Optional[str]”;应为“str””? - How to deal with "incompatible type "Optional[str]"; expected "str""? mypy错误,使用Union / Optional重载,“重载的函数签名1和2与不兼容的返回类型重叠” - mypy error, overload with Union/Optional, “Overloaded function signatures 1 and 2 overlap with incompatible return types” 如何处理 PyCharm 的“预期类型 X,得到 Y” - How to deal with PyCharm's "Expected type X, got Y instead"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM