如何使用相同的过载签名键入多个类似的Python函数
我有两个非常相似的功能,第二个函数将第一个函数调用(在实际代码中,此后执行其他操作)。
两者都采用两个可以采用多种类型的参数,两者都只有某些组合有意义,因此我使用过载来表明(实际代码也将增加无效组合)。 请参阅以下示例:
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
键入此类问题的正确方法是什么?
I have two functions that are quite similar, the second one calles the first one (and in the actual code does something else afterwards).
Both take two arguments that can take multiple types, both only certain combinations make sense, therefore I use overload to indicate that (the actual code will also raise for invalid combinations).
See the following example:
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)
Now mypy complains that:
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
What would be the correct way to type such a problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您已经在Python的
Overload
中达到了限制,虽然推荐写这篇文章,但这并不是真的。它太宽了,我不相信有任何方式。您将必须在
y
的实现签名和调用x
之间的某个时刻再次缩小类型。您可以做isInstance
检查,但是由于要花费一些东西,我个人只是#type:impanore [call-overload]
this。I think you've hit a limitation in python's
overload
, that whileis the recommended way to write this, it isn't strictly true. It's too broad and I don't believe there's any way round that. You're going to have to narrow the types again at some point between the implementation signature of
y
and callingx
. You could doisinstance
checks but since that costs something, I'd personally just# type: ignore[call-overload]
this.