通过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__
总结如下:
- build议实现
__eq__
而不是__cmp__
,除非你运行python <= 2.0(在2.1中已经添加了__eq__
) - 不要忘了也实现
__ne__
(应该是像return not self.__eq__(other)
或return not self == other
除非特殊情况除外) - 不要忘记,操作符必须在您想要比较的每个自定义类中实现(请参阅下面的示例)。
-
如果要与可以为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。