我有一个类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 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

其他回答

在你的类中实现__eq__方法;就像这样:

def __eq__(self, other):
    return self.path == other.path and self.title == other.title

编辑:如果你想让你的对象比较相等当且仅当它们有相等的实例字典:

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

在Python 3.7(及以上版本)中的数据类中,对象实例的相等性比较是一个内置特性。

Python 3.6提供了数据类的后端端口。

(Py37) nsc@nsc-vbox:~$ python
Python 3.7.5 (default, Nov  7 2019, 10:50:52) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from dataclasses import dataclass
>>> @dataclass
... class MyClass():
...     foo: str
...     bar: str
... 
>>> x = MyClass(foo="foo", bar="bar")
>>> y = MyClass(foo="foo", bar="bar")
>>> x == y
True

你应该实现方法__eq__:

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

      def __eq__(self,other):
           if not isinstance(other,MyClass):
                return NotImplemented
           else:
                #string lists of all method names and properties of each of these objects
                prop_names1 = list(self.__dict__)
                prop_names2 = list(other.__dict__)

                n = len(prop_names1) #number of properties
                for i in range(n):
                     if getattr(self,prop_names1[i]) != getattr(other,prop_names2[i]):
                          return False

                return True

下面通过在两个对象层次结构之间进行深度比较来工作(在我有限的测试中)。In处理各种情况,包括对象本身或其属性是字典的情况。

def deep_comp(o1:Any, o2:Any)->bool:
    # NOTE: dict don't have __dict__
    o1d = getattr(o1, '__dict__', None)
    o2d = getattr(o2, '__dict__', None)

    # if both are objects
    if o1d is not None and o2d is not None:
        # we will compare their dictionaries
        o1, o2 = o1.__dict__, o2.__dict__

    if o1 is not None and o2 is not None:
        # if both are dictionaries, we will compare each key
        if isinstance(o1, dict) and isinstance(o2, dict):
            for k in set().union(o1.keys() ,o2.keys()):
                if k in o1 and k in o2:
                    if not deep_comp(o1[k], o2[k]):
                        return False
                else:
                    return False # some key missing
            return True
    # mismatched object types or both are scalers, or one or both None
    return o1 == o2

这是一个非常棘手的代码,所以请在注释中添加任何可能不适合你的情况。

如果你想逐个属性进行比较,并查看它是否以及在哪里失败,你可以使用下面的列表推导式:

[i for i,j in 
 zip([getattr(obj_1, attr) for attr in dir(obj_1)],
     [getattr(obj_2, attr) for attr in dir(obj_2)]) 
 if not i==j]

这里的额外优势是,当在PyCharm中调试时,您可以压缩一行并在“Evaluate Expression”窗口中输入。