Python:__ cmp__和测试列表成员资格

时间:2015-03-05 21:09:24

标签: python comparison

如果某人已经解决了这个问题,请道歉,但我找不到答案。

我有一个问题,即我为自定义类覆盖了__cmp__,类似于:

class MyClass(object):
    def __init__(self, prop):
        self.prop = prop
    def __cmp__(self, other):
        return cmp(self.prop, other.prop)

a = MyClass(1)
b = MyClass(2)
c = MyClass(3)
d = MyClass(1)

my_list = [a, b, c]
print a in my_list
print b in my_list
print c in my_list
print d in my_list

# Output:
#
# True
# True
# True
# True

阅读文档告诉我这是预期的,因为:

  

对于列表和元组类型,当且仅当存在索引i使得x == y [i]为真时,y中的x才为真。

我的问题是双重的:

  • 为什么Python(2.7)使用==而不是is来测试列表成员资格?
  • 有更好的方法可以做到这一点,这样我可以测试我的类的特定实例是否实际上在容器中并且能够根据属性比较实例吗?

2 个答案:

答案 0 :(得分:1)

  
      
  • 为什么Python(2.7)使用==而不是is来测试列表成员资格?
  •   

因为对于包含检查,相等性通常比身份更有趣,特别是当两个不同的对象具有相同的值时。

>>> ('Hello, ' + 'world!') is 'Hello, world!'
False
>>> ('Hello, ' + 'world!') == 'Hello, world!'
True
  
      
  • 有没有更好的方法来做这个,这样我可以测试我的类的特定实例是否实际上在容器中并且能够根据其属性比较实例?
  •   

不是特别。

答案 1 :(得分:0)

列表包含一个等于变量的值,而不是对变量的引用。这样想吧。这两个代码示例是否相同?是什么让他们与众不同?

class Person:
    def __init__(self, name):
        self.name = name

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

# sample one

sam = Person('Sam')
bob = Person('Bob')

people = [sam, bob]

第一个示例是您应该使用is关键字。您正在尝试测试列表中的对象是否是列表外的对象,这意味着列表中的sam存储在内存中与列表外的sam相同的位置。

# sample two

sam = Person('Sam')
bob = Person('Bob')

people = [Person('Sam'), Person('Bob')]

此示例是您应该使用double equals关键字的时间。您正在尝试测试列表中的对象与列表外部的对象相比时是否具有该值。请注意,因为我们使用Sam的名称实例化给不同的人,所以它们的值相等但不是同一个对象。