Сравнение экземпляров объектов для равенства по их атрибутам в Python

Каков наилучший способ сравнить два экземпляра какого-либо объекта для равенства в Python? Я хотел бы иметь возможность сделать что-то вроде

Пример:

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

РЕДАКТИРОВАТЬ:

Дальнейшее разъяснение вопроса. Я бы хотел сравнить значения атрибутов и сделать более общее решение, чем

 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 

NB: __cmp__ в __eq__ , что перед Python 3.0 вы, скорее всего, __cmp__ использовать __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__ метод __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. Рекомендуется реализовать __eq__ а не __cmp__ , за исключением случаев, когда вы запускаете python <= 2.0 ( __eq__ был добавлен в 2.1)
  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__ для объекта.

Редактировать:

Как уже указывалось, функция __cmp__ устарела с 3,0. Вместо этого вы должны использовать методы «богатого сравнения» .

Я попробовал исходный пример (см. 7 выше), и он не работал в ipython. Обратите внимание, что cmp (obj1, obj2) возвращает «1» при реализации с использованием двух идентичных экземпляров объектов. Как ни странно, когда я изменяю одно из значений атрибута и переписываю, используя cmp (obj1, obj2), объект продолжает возвращать «1». (вздох…)

Хорошо, так что вам нужно сделать, это перебрать два объекта и сравнить каждый атрибут с помощью знака ==.

Экземпляр класса по сравнению с == приходит к неравному. Лучший способ – поместить функцию cmp в ваш класс, который будет делать материал.

Если вы хотите сделать сравнение по содержанию, вы можете просто использовать cmp (obj1, obj2)

В вашем случае cmp (doc1, doc2) Он вернет -1, если контент будет таким же.