如何使用相同的过载签名键入多个类似的Python函数

发布于 2025-01-29 13:58:50 字数 817 浏览 1 评论 0原文

我有两个非常相似的功能,第二个函数将第一个函数调用(在实际代码中,此后执行其他操作)。

两者都采用两个可以采用多种类型的参数,两者都只有某些组合有意义,因此我使用过载来表明(实际代码也将增加无效组合)。 请参阅以下示例:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日情怀 2025-02-05 13:58:50

我认为您已经在Python的Overload中达到了限制,虽然

def y(k: int | str, m: float | bytes) -> int | str:

推荐写这篇文章,但这并不是真的。它太宽了,我不相信有任何方式。您将必须在y的实现签名和调用x之间的某个时刻再次缩小类型。您可以做isInstance检查,但是由于要花费一些东西,我个人只是#type:impanore [call-overload] this。

I think you've hit a limitation in python's overload, that while

def y(k: int | str, m: float | bytes) -> int | str:

is 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 calling x. You could do isinstance checks but since that costs something, I'd personally just # type: ignore[call-overload] this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文