我有一个类MyClass,它包含两个成员变量foo和bar:

class MyClass:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

我有这个类的两个实例,每个实例都有相同的foo和bar值:

x = MyClass('foo', 'bar')
y = MyClass('foo', 'bar')

然而,当我比较它们是否相等时,Python返回False:

>>> x == y
False

我如何使python认为这两个对象相等?


当前回答

重写对象中的富比较运算符。

class MyClass:
 def __lt__(self, other):
      # return comparison
 def __le__(self, other):
      # return comparison
 def __eq__(self, other):
      # return comparison
 def __ne__(self, other):
      # return comparison
 def __gt__(self, other):
      # return comparison
 def __ge__(self, other):
      # return comparison

是这样的:

    def __eq__(self, other):
        return self._id == other._id

其他回答

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

    def __repr__(self):
        return str(self.value)

    def __eq__(self,other):
        return self.value == other.value

node1 = Node(1)
node2 = Node(1)

print(f'node1 id:{id(node1)}')
print(f'node2 id:{id(node2)}')
print(node1 == node2)
>>> node1 id:4396696848
>>> node2 id:4396698000
>>> True

我写了这个,并把它放在我的项目中的test/utils模块中。对于情况下,当它不是一个类,只是计划ol' dict,这将遍历两个对象,并确保

每个属性都与其对应的属性相等 不存在悬空属性(只存在于一个对象上的attrs)

它的大…这一点都不性感……但是,哦,boi,它工作!

def assertObjectsEqual(obj_a, obj_b):

    def _assert(a, b):
        if a == b:
            return
        raise AssertionError(f'{a} !== {b} inside assertObjectsEqual')

    def _check(a, b):
        if a is None or b is None:
            _assert(a, b)
        for k,v in a.items():
            if isinstance(v, dict):
                assertObjectsEqual(v, b[k])
            else:
                _assert(v, b[k])

    # Asserting both directions is more work
    # but it ensures no dangling values on
    # on either object
    _check(obj_a, obj_b)
    _check(obj_b, obj_a)

您可以通过删除_assert并使用普通的ol' assert来稍微清理它,但当它失败时,您得到的消息是非常没有帮助的。

总结如下:

It's advised to implement __eq__ rather than __cmp__, except if you run python <= 2.0 (__eq__ has been added in 2.1) Don't forget to also implement __ne__ (should be something like return not self.__eq__(other) or return not self == other except very special case) Don`t forget that the operator must be implemented in each custom class you want to compare (see example below). If you want to compare with object that can be None, you must implement it. The interpreter cannot guess it ... (see example below) class B(object): def __init__(self): self.name = "toto" def __eq__(self, other): if other is None: return False return self.name == other.name class A(object): def __init__(self): self.toto = "titi" self.b_inst = B() def __eq__(self, other): if other is None: return False return (self.toto, self.b_inst) == (other.toto, other.b_inst)

当比较对象的实例时,将调用__cmp__函数。

如果==操作符在默认情况下不适用,您总是可以为对象重新定义__cmp__函数。

编辑:

如上所述,__cmp__函数自3.0起已弃用。 相反,你应该使用“丰富比较”方法。

根据具体情况,你可以这样做:

>>> vars(x) == vars(y)
True

参见对象字段中的Python字典