我想编写一个通用函数,它采用实现所有实数运算的任何类型的实例(例如
int
、float
、fractions.Fraction
或第三方类型)。我发现 numbers.Real
ABC 非常适合在运行时通过 isinstance(x, numbers.Real)
检查强制执行类型,并且 Python 中的所有内置实数数字类型都注册为它的虚拟子类。
但我发现,虽然它对于运行时检查非常有效,但对于类型注释目的来说,它效果不佳,因为所有主要类型检查器都忽略
abc.ABC.register
的使用。那么如何注释我的参数来接受任何真实的数字类型呢?
这篇讨论中的帖子建议使用
typing.SupportsInt
协议来支持 numbers.Integral
ABC,但就我而言,我需要替代 numbers.Real
。此外,它仅检查类是否实现 __int__
,而不检查它是否支持所有积分运算。像 typing.SupportsReal
这样的东西不存在...我是否只需要定义自己的协议来检查所有实数运算 dunder 方法是否存在(__add__
,__sub__
,__mul__
,__div__
) 、__truediv__
等等...)?
一个简单的解决方案是执行以下操作: 假设您正在尝试将某个值乘以 2 并返回结果:
def multiply(n):
product = float(n) * 2
if product % 1 == 0:
return int(product)
else:
return product
所以基本上,将它转换为浮点数,做任何你想做的事情,然后检查它是否是整数,如果是,则将其转换为整数,如果不是,则保持原样。