Skip to main content
 首页 » 编程设计

python之我做错了什么(在 python 中通过重载实现替代相等)

2025年05月04日11think

有人在 SO 上问了一个关于如何在 python 中使用替代相等函数获取列表唯一函数的问题。

我在想可以通过继承元素类并重载相等函数来完成

import functools 
@functools.total_ordering 
class ffloat(float): 
def __eq__(self,other): 
    if floor(self) == floor(other): 
        return True 
    else: 
        return False 
def __le__(self,other): 
    if self == other: 
        return True 
    else: 
        return float(self) <= float(other) 
def __hash__(self): 
    return floor(self) 
 
 
a = map(ffloat,[4.3,8,8.9, 13]) 
 
 
In [41]: a[1] == a[2] 
Out[41]: True 

但是

In [42]: set(a) 
Out[42]: set([4.3, 8.0, 8.9, 13.0]) 

编辑:将 abs < 1.5 equality 替换为 floor equality
添加哈希 附言有没有办法从这个类和两个 lambda 中创建一个类工厂,并返回一个继承自第一个覆盖所需的相等函数的类。

请您参考如下方法:

这不是一个有效的相等函数,因为它不是 transitive :

mfloat(0) == mfloat(1) == mfloat(2),但是 mfloat(0) != mfloat(2)。

另请注意,为了在集合中使用,您必须覆盖 __hash__因此,以下属性适用于您的类的所有实例 a、b:

a == b ⇒ hash(a) == hash(b) 

set 发现 hash(mfloat(8)) != hash(mfloat(9))。由于 set 假定上述属性成立,因此它得出 mfloat(8) != mfloat(9) 而无需实际调用 __eq__。


总之,这是可行的:

from math import floor 
class ffloat(float): 
    def __eq__(self,other): 
        return floor(self) == floor(other): 
    def __hash__(self): 
        return floor(self) 
 
a = map(ffloat,[4.3,8,8.9, 13]) 
print(set(a)) 
# output: {8.0, 4.3, 13.0}