缩小函数内部参数的联合类型

Narrow down Union type of argument inside function

我有一个函数接受一个类型为 A 或 B 的参数。如果 A 被传递,它会被转换为 B 以供内部进一步处理。

为简单起见,考虑以下使用 int/float 的示例来说明该场景:

import typing


def foo(x: typing.Union[int, float]):
    if type(x) is int:
        x = float(x)

    x.as_integer_ratio()  # method of float that does not exist for int

最后一行导致 mypy 错误:

error: Item "int" of "Union[int, float]" has no attribute "as_integer_ratio"

有没有一个很好的方法让 mypy 清楚,在 if 之后 x 的类型基本上从 Union 变成了 float 而不添加额外的变量?

您应该将 if 语句更改为:

if isinstance(x, int):

这一行由 mypy 处理得更好,现在在执行 ifx = float(x) 后它明白 x 不能是 int 并且错误消失了。