从功能返回类型中缩小类型

发布于 2025-01-31 18:04:32 字数 695 浏览 1 评论 0原文

我的函数可能会返回两种不同类型的值,例如union [str,int]。返回值的类型可以从函数参数确定。因此,在每个通话中,我知道应该返回哪种类型。但是,Mypy抱怨说union [str,int]不能分配给更严格的类型,例如str。有没有一种方法可以允许更严格的类型分配,而无需完全关闭签名(例如##type:imploore注释)?

例如,如果我具有此功能:

from typing import Union


def change_value(action: str, value: int) -> Union[str, int]
    if action == "stringify":
        return str(value)
    return value

stringified_value: str
stringified_value = change_value("stringify", 10)

Mypy会出现此错误:

Expression of type "str | int" cannot be assigned to declared type "str"

我想通过以某种方式告诉Mypy来删除Mypy错误,那么在这种情况下,在这种情况下,缩小缩小始终是正确的。

I have a function which might return values of two different types, e.g. Union[str, int]. The type of the returned value can be determined from the function argument. So on each call, I know which type should be returned. However, mypy complains that Union[str, int] type cannot be assigned to a stricter type, e.g. str. Is there a way to allow stricter type assignment, without completely turning type checking off (e.g. with # type: ignore comment)?

For example, if I have this function:

from typing import Union


def change_value(action: str, value: int) -> Union[str, int]
    if action == "stringify":
        return str(value)
    return value

stringified_value: str
stringified_value = change_value("stringify", 10)

Mypy complains with this error:

Expression of type "str | int" cannot be assigned to declared type "str"

I would like to remove mypy error by somehow telling mypy, that in this case type narrowing down is always correct.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

一抹淡然 2025-02-07 18:04:32

可以使用Overloads进行:

from typing import Literal, Union, overload

@overload
def change_value(action: Literal['stringify'], value: int) -> str: ...
@overload
def change_value(action: Literal['whatever_else'], value: int) -> int: ...

def change_value(action: str, value: int) -> Union[str, int]:
    if action == "stringify":
        return str(value)
    return value

stringified_value: str = change_value("stringify", 10)

”还有一个附加的好处:您明确地说Stringifywhywing_else是两个可能的操作,然后呼叫thats_value('Stingify',2)>将被类型的检查器拒绝(注意到错字?如果没有,则很难调试否则)。

It can be done using overloads:

from typing import Literal, Union, overload

@overload
def change_value(action: Literal['stringify'], value: int) -> str: ...
@overload
def change_value(action: Literal['whatever_else'], value: int) -> int: ...

def change_value(action: str, value: int) -> Union[str, int]:
    if action == "stringify":
        return str(value)
    return value

stringified_value: str = change_value("stringify", 10)

playground

This approach has an additional benefit: you explicitly tell that stringify and whatever_else are two only possible actions, and call like change_value('stingify', 2) will be denied by type checker (noticed the typo? If not, it would be hard to debug otherwise).

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