有没有办法检查两个对象在python中的每个变量中是否包含相同的值?

时间:2011-06-21 10:28:00

标签: python object match

如何检查

的两个实例
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)

5 个答案:

答案 0 :(得分:36)

如果您希望==有效,请在班级中实施__eq__方法以执行丰富的比较。

如果你想要做的就是比较所有属性的相等性,你可以通过比较每个对象中的__dict__来简洁地做到这一点:

class MyClass:

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

答案 1 :(得分:3)

对于任意对象,==运算符仅在两个对象是同一对象时才返回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。您可能希望首先检查与之比较的对象是具有isinstance(其他,FooBar)的FooBar实例。默认情况下不会这样做,因为在某些情况下您可能希望返回True以便在不同类型之间进行比较。

请参阅AJ的答案,以便更简单地比较所有不应抛出属性错误的参数。

有关丰富比较的详细信息,请参阅the python docs

答案 2 :(得分:0)

为避免向模型添加或删除属性并忘记对__eq__函数进行适当更改,可以按如下方式对其进行定义。

def __eq__(self, other):
    if self.__class__ == other.__class__:
        fields = [field.name for field in self._meta.fields]
        for field in fields:
            if not getattr(self, field) == getattr(other, field):
                return False
        return True
    else:
        raise TypeError('Comparing object is not of the same type.')

以这种方式,比较所有对象属性。现在,您可以使用object.__eq__(other)object == other检查属性相等性。

答案 3 :(得分:0)

根据Lutz的《学习Python》,“ ==”运算符测试值的等效性,以递归方式比较所有嵌套对象。 “ is”运算符测试两个对象是否为同一对象,即,内存中的地址是否相同(指针值相同)。 除了小整数和简单字符串的缓存/重用外,两个对象(例如x = [1,2]和y = [1,2])的值均等于“ ==”,但 y“ is” x < / em>返回false。两个浮点数x = 3.567和y = 3.567时也是如此。这意味着它们的地址是不同的,换句话说就是hex(id(x))!= hex(id(y))。

对于类对象,我们必须重写方法__eq __()来创建两个A类对象,例如x = A(1,[2,3])和y = A(1,[2,3])“ ==” in内容。默认情况下,class object "=="在这种情况下只求比较id和id(x)!= id(y),因此x!= y。 总之,如果x“是” y,则x == y,但相反的说法不正确。

答案 4 :(得分:0)

如果这是您想在测试中使用的东西,您只想验证简单对象的字段是否相等,请查看 testfixtures 中的 compare

from testfixtures import compare

compare(a, b)