如何检查
的两个实例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)
答案 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)