通过Python中的属性比较对象实例的相等性

在Python中比较两个平等对象实例的最佳方法是什么? 我希望能够做到这样的事情

例:

doc1 = ErrorDocument(path='/folder',title='Page') doc2 = ErrorDocument(path='/folder',title='Page') if doc1 == doc2: # this should be True #do something 

编辑:

为了进一步澄清这个问题。 我想通过属性值进行比较,并且比通常的解决scheme更有用

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

__eq__()方法应该是这样的吗?

 def __eq__(self, other): # Is the other instance of the same object # Loop through __dict__ and compare values to attributes of other 

和往常一样,Python是KISS :

 class Test(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def __str__(self): return str(self.__dict__) def __eq__(self, other): return self.__dict__ == other.__dict__ t1 = Test("foo", 42) t2 = Test("foo", 42) t3 = Test("bar", 42) print t1, t2, t3 print t1 == t2 print t2 == t3 

它输出:

 {'attr2': 42, 'attr1': 'foo'} {'attr2': 42, 'attr1': 'foo'} {'attr2': 42, 'attr1': 'bar'} True False 

注意:请注意,在Python 3.0之前,您更可能使用__cmp__而不是__eq__ ,工作方式相同。

您可以覆盖对象中丰富的比较运算符 。

 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 

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

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

编辑:如果你希望你的对象比较相等当且仅当他们有平等的实例字典:

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

总结如下:

  1. build议实现__eq__而不是__cmp__ ,除非你运行python <= 2.0(在2.1中已经添加了__eq__
  2. 不要忘了也实现__ne__ (应该是像return not self.__eq__(other)return not self == other除非特殊情况除外)
  3. 不要忘记,操作符必须在您想要比较的每个自定义类中实现(请参阅下面的示例)。
  4. 如果要与可以为None的对象进行比较,则必须实现它。 口译员不能猜出来…(见下面的例子)

     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开始被弃用。 相反,你应该使用“丰富的比较”方法。

如果你想得到一个属性的属性比较,看看是否失败,你可以使用下面的列表理解:

 [i for i,j in zip([getattr(committed_vans_events[0][0].request, attr) for attr in dir(committed_vans_events[0][0].request)], [getattr(self.vans_states[0].onboard_passengers[0], attr) for attr in dir(self.vans_states[0].onboard_passengers[0])]) if not i==j] 

这里额外的好处是你可以在PyCharm中debugging一行,并在“Evaluate Expression”窗口中input。

我尝试了最初的例子(见上面的7),并没有在ipython中工作。 请注意,当使用两个相同的对象实例实现时,cmp(obj1,obj2)返回“1”。 奇怪的是,当我修改其中一个属性值和recompare,使用cmp(obj1,obj2)对象继续返回一个“1”。 (叹…)

好吧,所以你需要做的是迭代两个对象,并使用==符号比较每个属性。

与==相比的类的实例变得不相等。 最好的方法是把cmp的function到你的class上去做。

如果你想通过内容做比较,你可以简单地使用cmp(obj1,obj2)

在你的情况下,cmp(doc1,doc2)如果内容明智,它们将返回-1。