我有一个函数,可以在给定布尔输入参数的情况下返回不同类型.目前,我只使用Union对其进行注释:

def fn(x: int, ret_str: bool) -> Union[int, str]:
  if ret_str:
    return str(x)
  else:
    return x

但是,如果我这样注释,该函数的输出也将被类型化为联合类型.

out = fn(8, ret_str=False)  # out will have type Union[int, str] but we know it's int

有没有办法注释它,以便类型判断器知道如果我使用文字False调用函数,返回类型必须是int而不是str

推荐答案

是的,使用typing模块和overload/Literal可以做到这一点.这不是最好的解决方案,因为它非常冗长(与大多数类型化语言相比),但会导致类型判断器根据传递的参数关联返回类型.在大多数情况下,我可能会避免在库/模块或其他代码之外执行此操作,因为我知道这些代码将从外部源重复引用.

from typing import Literal, overload


@overload
def fn(x: int, ret_str: Literal[False]) -> int:
    ...


@overload
def fn(x: int, ret_str: Literal[True]) -> str:
    ...


def fn(x: int, ret_str: bool) -> int | str:
    if ret_str:
        return str(x)
    return x

如果要像这样实现更高级的类型判断,将此信息存储在单独的pyi文件中而不是直接存储在程序中通常是有益的.

最后,请注意,@overload修饰符纯粹是用于类型判断的.您不能使用它将不同的功能放入一个函数中,因为函数的最终声明将始终覆盖之前的任何定义(无论是否使用了修饰符).因此,在重载函数定义中添加省略号(...)是一种范例.

Python相关问答推荐

Python panda拆分列保持连续多行

如何使用entry.bind(FocusIn,self.Method_calling)用于使用网格/列表创建的收件箱

在Pandas框架中截短至固定数量的列

如何通过多2多字段过滤查询集

如何根据另一列值用字典中的值替换列值

在Python中对分层父/子列表进行排序

'discord.ext. commanders.cog没有属性监听器'

如何避免Chained when/then分配中的Mypy不兼容类型警告?

如何将Docker内部运行的mariadb与主机上Docker外部运行的Python脚本连接起来

我如何使法国在 map 中完全透明的代码?

我如何根据前一个连续数字改变一串数字?

使用NeuralProphet绘制置信区间时出错

字符串合并语法在哪里记录

如何保持服务器发送的事件连接活动?

基于行条件计算(pandas)

在Python中使用yaml渲染(多行字符串)

如何找出Pandas 图中的连续空值(NaN)?

OpenGL仅渲染第二个三角形,第一个三角形不可见

合并相似列表

如何根据一定条件生成段id