覆盖 python 的浮点数以进行不精确比较 - 哈希实现
Override python's float for inexact comparison - hash implementation
我 运行 遇到了一个有趣的问题 - 这是一个不精确比较的浮点数重写:
class Rounder(float):
"""Float wrapper used for inexact comparison."""
__slots__ = ()
def __hash__(self):
raise NotImplementedError
def __eq__(self, b, rel_tol=1e-06, abs_tol=1e-12):
"""Check if the two floats are equal to the sixth place (relatively)
or to the twelfth place (absolutely)."""
try:
return abs(self - b) <= max(rel_tol * max(abs(self), abs(b)),
abs_tol) # could use math.isclose
except TypeError:
return NotImplemented
...
要求是相等的对象具有相等的哈希值——但似乎无法想出一个公式来表示将比较相同的所有 Rounder(float) 实例(因此将它们全部映射到相同的哈希值).网络上的大多数建议都是关于如何为 类 定义 hash/equals 的,这些建议基于某些(不可变的)属性进行比较 - 不适用于这种情况。
没有对这些对象进行哈希处理的有效方法。散列需要 ==
的传递定义,而您的对象没有。即使你做了类似 def __hash__(self): return 0
的事情,==
的不传递性仍然会使你的对象不安全地用作字典键。
非传递性是不以这种方式定义==
的重要原因之一。如果您想进行接近度检查,请使用 math.isclose
明确执行此操作。不要进行该操作 ==
.
我 运行 遇到了一个有趣的问题 - 这是一个不精确比较的浮点数重写:
class Rounder(float):
"""Float wrapper used for inexact comparison."""
__slots__ = ()
def __hash__(self):
raise NotImplementedError
def __eq__(self, b, rel_tol=1e-06, abs_tol=1e-12):
"""Check if the two floats are equal to the sixth place (relatively)
or to the twelfth place (absolutely)."""
try:
return abs(self - b) <= max(rel_tol * max(abs(self), abs(b)),
abs_tol) # could use math.isclose
except TypeError:
return NotImplemented
...
要求是相等的对象具有相等的哈希值——但似乎无法想出一个公式来表示将比较相同的所有 Rounder(float) 实例(因此将它们全部映射到相同的哈希值).网络上的大多数建议都是关于如何为 类 定义 hash/equals 的,这些建议基于某些(不可变的)属性进行比较 - 不适用于这种情况。
没有对这些对象进行哈希处理的有效方法。散列需要 ==
的传递定义,而您的对象没有。即使你做了类似 def __hash__(self): return 0
的事情,==
的不传递性仍然会使你的对象不安全地用作字典键。
非传递性是不以这种方式定义==
的重要原因之一。如果您想进行接近度检查,请使用 math.isclose
明确执行此操作。不要进行该操作 ==
.