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

36 投票
6 回答
54736 浏览
提问于 2025-04-16 19:59

我怎么检查两个

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)

6 个回答

6

对于任意一个对象,==这个操作符只有在两个对象是同一个对象时才会返回真,也就是说,它们必须指向内存中的同一个地址。

如果你想要更灵活的比较方式,就需要重写一些特殊的比较操作符,这里特别是__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)来检查。默认情况下并不会这样做,因为有些情况下你可能希望不同类型的对象之间比较时返回真。

想要更整洁的方式来比较所有参数,并且不会抛出属性错误,可以参考AJ的回答。

关于丰富比较的更多信息,可以查看Python文档

8

从Python 3.7开始,你可以使用dataclass这个功能,轻松检查你想要的内容。比如说:

from dataclasses import dataclass

@dataclass
class FooBar:
    param: str
    param2: float
    param3: int

a = Foobar("test_text",2.0,3)
b = Foobar("test_text",2.0,3)

print(a==b)

这段代码会返回True

58

如果你想让 == 这个比较符号能正常工作,那就需要在你的类里面实现一个叫 __eq__ 的方法,这个方法可以帮助你进行更复杂的比较。

如果你只是想比较两个对象的所有属性是否相等,你可以很简单地通过比较每个对象的 __dict__ 来实现:

class MyClass:

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

撰写回答