我有一个带有多个默认值的Kwarg的函数.其中一个(在中间的某个地方)是一个控制返回类型的布尔切换.

我想用Literal[True/False]为这个方法创建两个重载,但保留默认值.

我的 idea 如下:

from typing import overload, Literal

@overload
def x(a: int = 5, t: Literal[True] = True, b: int = 5) -> int: ...

@overload
def x(a: int = 5, t: Literal[False] = False, b: int = 5) -> str: ...

def x(a: int = 5, t: bool = True, b: int = 5) -> int | str:
    if t:
        return 5
    return "asd"

但mypy提出:

错误:重载函数签名1和2与不兼容的返回类型重叠

我想这是因为x()人会发生冲突.

但我无法删除第二个重载中的默认值= False,因为它前面是带有默认值的arg a.

我怎样才能正确地使其过载

  • x()int
  • x(t=True)int
  • x(t=False)str

推荐答案

这是一个老问题.原因是您在这两个分支中都指定了默认值,因此在这两个分支中都可以使用x(),并且返回类型未定义.

对于这种情况,我有以下模式:

from typing import overload, Literal

@overload
def x(a: int = 5, t: Literal[True] = True, b: int = 5) -> int: ...

@overload
def x(a: int = 5, *, t: Literal[False], b: int = 5) -> str: ...

@overload
def x(a: int, t: Literal[False], b: int = 5) -> str: ...

def x(a: int = 5, t: bool = True, b: int = 5) -> int | str:
    if t:
        return 5
    return "asd"

为什么,如何?你必须考虑调用函数的方法.首先,你可以提供a,然后t可以作为kwarg(#2)或arg(#3)给出.你也可以保留a个默认值,那么t总是一个kwarg(#2).这是为了防止把arg放在kwarg后面,kwarg是SyntaxError.在多个参数上重载比较困难,但也可能是这样:

@overload
def f(a: int = 1, b: Literal[True] = True, c: Literal[True] = True) -> int: ...

@overload
def f(a: int = 1, *, b: Literal[False], c: Literal[True] = True) -> Literal['True']: ...

@overload
def f(a: int = 1, *, b: Literal[False], c: Literal[False]) -> Literal['False']: ...

@overload
def f(a: int, b: Literal[False], c: Literal[True] = True) -> Literal['True']: ...

@overload
def f(a: int, b: Literal[False], c: Literal[False]) -> Literal['False']: ...

def f(a: int = 1, b: bool = True, c: bool = True) -> int | Literal['True', 'False']:
    return a if b else ('True' if c else 'False')  # mypy doesn't like str(c)

你可以玩超载here.

Python相关问答推荐

重置PD帧中的值

pandas fill和bfill基于另一列中的条件

在numpy数组中寻找楼梯状 struct

在电影中向西北方向对齐""

仅取消堆叠最后三列

与同步和异步客户端兼容的Python函数

高效地计算数字数组中三行上三个点之间的Angular

将鼠标悬停在海运`pairplot`的批注/高亮显示上

极地数据帧:ROLING_SUM向前看

使用_in链接操作管道传输的中间结果是否可用于链中的后续函数?

如何从NumPy数组中提取主频?

如何正确设置ALLOWED_HOST以允许网络中的其他计算机访问Web

我如何区分PyTorch张量和嵌套张量?

PythonC扩展比Numba JIT快吗?

真正的Python散布函数

没有目标的验证数据

如何使用数据帧的一列和最后一行对数据帧进行分组?

在matplotlib中将标题的一部分设置为粗体和正常

在Python中使用";swmm_api";包中的";lid_use";时出错?

如何将按钮移动到按钮在GRadio中使用或更改的框之前?