Python 类型注释的包罗万象的重载

Sea*_*sey 10 python overloading mypy python-typing

下面的代码失败mypy并显示error: Overloaded function signatures 1 and 2 overlap with incompatible return types.

@overload
def test_overload(x: str) -> str: ...

@overload
def test_overload(x: object) -> int: ...

def test_overload(x) -> Union[str, int]:
    if isinstance(x, str):
        return x
    else:
        return 1
Run Code Online (Sandbox Code Playgroud)

我想要表达的是:“这个函数接受一个任意的Python对象。如果该对象是一个字符串,它返回一个字符串。如果它是任何其他类型,它返回一个整数。注意这个特定的例子是为了表示一般情况。

可以用重载来表达吗?

ale*_*ame 6

目前(Python 3.10,mypy 0.961)没有办法表达除一个之外的任何对象。但您可以type: ignore[misc]对例外类型使用忽略。它们必须先于更一般的变体,因为@overload顺序很重要:

from typing import overload, Union


@overload
def test_overload(x: str) -> str:  # type: ignore[misc]
    ...


@overload
def test_overload(x: object) -> int:
    ...


def test_overload(x) -> Union[str, int]:
    if isinstance(x, str):
        return x
    else:
        return 1


reveal_type(test_overload("string"))  # Revealed type is "builtins.str"
reveal_type(test_overload(object()))  # Revealed type is "builtins.int"
Run Code Online (Sandbox Code Playgroud)

  • 是的,尽管有错误输出,mypy 仍能正确推断类型。但在使用重载时,我认为它更像是一种解决方法,而不是直接的解决方案。我们在这里允许一些不安全的情况,您可以在[此处](https://mypy.readthedocs.io/en/stable/more_types.html#type-checking-the-variants)阅读相关内容 (2认同)