代码之家  ›  专栏  ›  技术社区  ›  Željko Živković

通过对象实例在python中的属性比较对象实例是否相等

  •  187
  • Željko Živković  · 技术社区  · 15 年前

    在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
    
    8 回复  |  直到 6 年前
        1
  •  268
  •   Sergey Slepov    7 年前

    和巨蟒一样, 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
    

    注意:在Python3.0之前,您更可能使用 __cmp__ 而不是 __eq__ 以同样的方式工作。

        2
  •  43
  •   Community Bob Smith    6 年前

    你超越了 rich comparison operators 在你的目标中。

    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
    

    这样地:

        def __eq__(self, other):
            return self._id == other._id
    
        3
  •  5
  •   Kiv    15 年前

    实施 __eq__ 类中的方法;类似于:

    def __eq__(self, other):
        return self.path == other.path and self.title == other.title
    

    编辑:如果希望对象在具有相同实例字典的情况下比较相等:

    def __eq__(self, other):
        return self.__dict__ == other.__dict__
    
        4
  •  4
  •   fievel    8 年前

    作为总结:

    1. 建议实施 __eq__ 而不是 __cmp__ ,除非运行python<=2.0( 爱斯克 已在2.1中添加)
    2. 别忘了也要实施 __ne__ (应该是 return not self.__eq__(other) return not self == other 除了非常特殊的情况)
    3. 不要忘记,必须在要比较的每个自定义类中实现运算符(参见下面的示例)。
    4. 如果要与不能为空的对象进行比较,则必须实现它。翻译无法猜测…(见下例)

      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)
      
        5
  •  3
  •   bignose    9 年前

    当比较对象的实例时, __cmp__ 调用函数。

    如果默认情况下,==运算符不适用于您,则可以始终重新定义 α-CMPa 对象的函数。

    编辑:

    正如已经指出的那样, α-CMPa 函数自3.0以来已弃用。 相反,您应该使用 “rich comparison” 方法。

        6
  •  0
  •   DalyaG    7 年前

    如果您希望通过属性比较获得一个属性,并查看它是否失败以及失败的位置,可以使用以下列表理解:

    [i for i,j in 
     zip([getattr(committed_vans_events[0][0].request, attr) 
          for attr in dir(committed_vans_events[0][0].request)],
         [getattr(self.vans_states[0].onboard_passengers[0], attr) 
          for attr in dir(self.vans_states[0].onboard_passengers[0])]) 
     if not i==j]
    

    这里的额外优势是,在Pycharm中调试时,您可以将其压缩一行并进入“Evaluate Expression”窗口。

        7
  •  -1
  •   user2215595    11 年前

    我尝试了最初的例子(见上面的7),但它在ipython中不起作用。注意,当使用两个相同的对象实例实现时,CMP(obj1、obj2)返回“1”。奇怪的是,当我修改一个属性值并重新编译时,使用cmp(obj1,obj2),对象继续返回“1”。(叹气…)

    好的,所以您需要做的是迭代两个对象,并使用==符号比较每个属性。

        8
  •  -4
  •   Lesmana    12 年前

    当与==比较时,类的实例不相等。最好的办法是 化学机械抛光 为你的班级做功课。

    如果要按内容进行比较,只需使用cmp(obj1、obj2)

    对于CMP(doc1,doc2),如果内容相同,它将返回-1。