Есть ли способ проверить, содержат ли два объекта одинаковые значения в каждой из своих переменных в Python? - PullRequest
18 голосов
/ 21 июня 2011

Как проверить, идентичны ли два экземпляра

class FooBar(object):
    __init__(self, param):
        self.param = param
        self.param_2 = self.function_2(param)
        self.param_3 = self.function_3()

?Под идентичным я подразумеваю, что они имеют одинаковые значения во всех своих переменных.

a = FooBar(param)
b = FooBar(param)

Я думал о

if a == b:
    print "a and b are identical"!

Будет ли это делать без побочных эффектов?

Фон для моего вопроса - юнит-тестирование.Я хочу достичь чего-то вроде:

self.failUnlessEqual(self.my_object.a_function(), another_object)

Ответы [ 3 ]

36 голосов
/ 21 июня 2011

Если вы хотите, чтобы == работал, то реализуйте метод __eq__ в своем классе, чтобы выполнить расширенное сравнение.

Если все, что вы хотите сделать, это сравнить равенство всех атрибутов, вы можете сделать это кратко, сравнив __dict__ в каждом объекте:

class MyClass:

    def __eq__(self, other) : 
        return self.__dict__ == other.__dict__
3 голосов
/ 21 июня 2011

Для произвольного объекта оператор == вернет true, только если два объекта являются одним и тем же объектом (т. Е. Если они ссылаются на один и тот же адрес в памяти).

Чтобы получить больше «сделанных на заказ»поведения, вы захотите переопределить операторы расширенного сравнения, в данном случае конкретно __eq__.Попробуйте добавить это к своему классу:

def __eq__(self, other):
    if self.param == other.param \
    and self.param_2 == other.param_2 \
    and self.param_3 == other.param_3:
        return True
    else:
        return False

(сравнение всех параметров можно было бы провести здесь, но я оставил их для ясности).

Обратите внимание, что если параметры сами являются объектами, которые вы определили, эти объекты должны будут определить __eq__ аналогичным образом, чтобы это работало.

Еще один момент, на который следует обратить внимание: есливы пытаетесь сравнить объект FooBar с другим типом объекта, как я это делал выше, python попытается получить доступ к атрибутам param, param_2 и param_3 другого типа объекта, которые будут вызывать AttributeError.Вы, вероятно, захотите сначала проверить объект, с которым сравниваете, экземпляр FooBar с isinstance (other, FooBar).Это не сделано по умолчанию, так как могут быть ситуации, когда вы хотите вернуть True для сравнения между различными типами.

См. Ответ AJ для более простого способа сравнить все параметры, которые также не должны бросать атрибутошибка.

Для получения дополнительной информации о расширенном сравнении см. документы по питону .

0 голосов
/ 23 июня 2017

Чтобы исключить возможность добавления или удаления атрибутов в модель и забыть внести соответствующие изменения в функцию __eq__, вы можете определить ее следующим образом.атрибуты объекта сравниваются.Теперь вы можете проверить равенство атрибутов с помощью object.__eq__(other) или object == other.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...