我有两个非常相似的函数,第二个函数调用第一个函数(然后在实际代码中执行其他操作)。
两者都采用两个可以采用多种类型的参数,两者都只有某些组合才有意义,因此我使用重载来指示(实际代码也会引发无效组合)。 请参阅以下示例:
from typing import overload
@overload
def x(k: int, m: float) -> int:
...
@overload
def x(k: str, m: bytes) -> str:
...
def x(k: int | str, m: float | bytes) -> int | str:
return k
@overload
def y(k: int, m: float) -> int:
...
@overload
def y(k: str, m: bytes) -> str:
...
def y(k: int | str, m: float | bytes) -> int | str:
return x(k, m)
现在 mypy 抱怨说:
error: No overload variant of "x" matches argument type "Union[int, str]" [call-overload]
note: Possible overload variants:
note: def x(k: int, m: float) -> int
note: def x(k: str, m: bytes) -> str
输入此类问题的正确方法是什么?
我认为你已经遇到了Python的限制
overload
,同时
def y(k: int | str, m: float | bytes) -> int | str:
是推荐的写法,但严格来说并不正确。它太宽泛了,我不相信有任何办法可以解决这个问题。您必须在
y
的实现签名和调用 x
之间的某个时刻再次缩小类型范围。您可以进行 isinstance
检查,但由于这会花费一些费用,我个人只会 # type: ignore[call-overload]
这个。