解决方案的关键是构建一个重写的包装器__eq__
方法并将其替换为近似匹配:
import cmath
class Approximately(complex):
def __new__(cls, x, /, **kwargs):
result = complex.__new__(cls, x)
result.kwargs = kwargs
return result
def __eq__(self, other):
try:
return isclose(self, other, **self.kwargs)
except TypeError:
return NotImplemented
它为浮点值和复数值创建近似相等测试:
>>> Approximately(1.1 + 2.2) == 3.3
True
>>> Approximately(1.1 + 2.2, abs_tol=0.2) == 3.4
True
>>> Approximately(1.1j + 2.2j) == 0.0 + 3.3j
True
以下是如何在 match/case 语句中使用它:
for x in [sum([0.1] * 10), 1.1 + 2.2, sin(radians(45))]:
match Approximately(x):
case 1.0:
print(x, 'sums to about 1.0')
case 3.3:
print(x, 'sums to about 3.3')
case 0.7071067811865475:
print(x, 'is close to sqrt(2) / 2')
case _:
print('Mismatch')
这输出:
0.9999999999999999 sums to about 1.0
3.3000000000000003 sums to about 3.3
0.7071067811865475 is close to sqrt(2) / 2