我想重载下面的函数,因此如果传递了支持int()个Python类型的值,则提示int,否则Python类型提示传递的值.

Python typing模块提供了一个SupportsInt类型,我们可以使用它来判断我们的值是否支持int.

from typing import Any, SupportsInt, overload

@overload
def to_int(value: SupportsInt) -> int: ...

@overload
def to_int[T: NotSupportsInt???](value: T) -> T: ...

def to_int(value: Any) -> Any:
    try:
        return int(value)
    except TypeError:
        return value

但在我们的第二个overload声明中,我们如何指定所有不支持int的值呢?

推荐答案

类型做出positive个promise --它们指定对象can do的事情.不是对象can't所做的事情.

如果您有一个静态类型float的对象,则您知道该对象支持__int__,因此您知道它是类型SupportsInt的成员.

如果您有静态类型object的对象,则object没有__int__方法,但this object仍然可能支持__int__.该对象可以是一个float,也可以是支持__int__object的其他子类的实例.您don't know是否将其传递给to_int都会返回int.

您的第二个超载是试图说"不支持__int__?然后返回原始类型."它should说的是"不知道它是否支持__int__?然后可能返回原始类型,或者可能返回int."您可以使用无界类型变量和联合返回类型来实现这一点,就像这样:

from typing import overload, SupportsInt, TypeVar

T = TypeVar('T')

@overload
def to_int(value: SupportsInt) -> int: ...

@overload
def to_int(value: str) -> int: ...

@overload
def to_int(value: T) -> T | int: ...

def to_int(value):
    try:
        return int(value)
    except TypeError:
        return value

请注意,我还为str添加了一个单独的过载.str实际上不支持__int__,因此它不属于SupportsInt过载范围-像int('35')这样的呼叫由int.__new__中的特殊情况处理.

当然,有时您会遇到类似to_int([])的情况,其中您知道对象的具体具体类型,并且您know int调用将会失败.但类型系统不会以更具体的注释发挥作用所需的方式传播该信息.对于类型判断器来说,list的实例可能是某个奇怪的支持__int__list子集的实例,即使查看代码的人可以看出它不是.

Python相关问答推荐

无法在Python中使用Selenium标记正确的元素以抓取网站

如何从维基百科的摘要部分/链接列表中抓取链接?

合并其中一个具有重叠范围的两个框架的最佳方法是什么?

Pandas 按照特殊规则保留每n行

云上Gunicorn的Flask-socketIO无法工作

如何在Pygame中绘制右对齐的文本?

为什么我的(工作)代码(生成交互式情节)在将其放入函数中时不再工作?

如何使用PyTest根据self 模拟具有副作用的属性

这家einsum运营在做什么?E = NP.einsum(aj,kl-il,A,B)

"Discord机器人中缺少所需的位置参数ctx

如何终止带有队列的Python进程?+ 队列大小的错误?

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

连接两个具有不同标题的收件箱

Pytest两个具有无限循环和await命令的Deliverc函数

如何使用数组的最小条目拆分数组

数据抓取失败:寻求帮助

"使用odbc_connect(raw)连接字符串登录失败;可用于pyodbc"

从spaCy的句子中提取日期

将pandas导出到CSV数据,但在此之前,将日期按最小到最大排序

Pandas GroupBy可以分成两个盒子吗?