2015-03-05 4 views
0

Извиняется, если кто-то уже обращался к этому, но я не смог найти ответ.Python: __cmp__ и членство в списке тестирования

У меня есть проблема, когда я отменяю __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 

Чтение документации говорит мне, что это, как ожидается, потому что:

Для списка и tuple, x в y истинно тогда и только тогда, когда существует индекс i такой, что x == y [i] истинно.

Мой вопрос два раза:

  • Почему Python (2.7) использовать == вместо is, чтобы проверить членство в списке?
  • Есть ли лучший способ сделать это, чтобы я мог проверить, действительно ли конкретный экземпляр моего класса находится в контейнере и, чтобы сравнить экземпляры на основе их атрибутов?
+1

В списке содержится значение, равное переменной, а не ссылка на переменную. –

+0

На самом деле я добавил 'print a is my_list [0]; print d является my_list [0] 'и получил' True' и 'False' соответственно.Разве это не означает, что он содержит сам экземпляр? –

+0

Да, см. Мой ответ для большего. –

ответ

1
  • Почему Python (2.7) использовать == вместо is, чтобы проверить членство в списке?

Поскольку равенство, как правило, более интересным, чем идентичности для проверки сдерживания, особенно, когда два разных объекта могут иметь одинаковое значение.

>>> ('Hello, ' + 'world!') is 'Hello, world!' 
False 
>>> ('Hello, ' + 'world!') == 'Hello, world!' 
True 
  • Есть ли лучший способ делать это, так что я могу проверить, действительно ли конкретный экземпляр моего класса в контейнере и быть в состоянии сравнить экземпляры на основе их атрибутов?

Не особо.

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] 

Первый образец, когда вы должны использовать ключевое слово. Вы пытаетесь проверить, является ли объект в списке объектом вне списка, что означает, что сам внутри списка хранится в том же месте в памяти, что и сам вне списка.

# sample two 

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

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

Этот образец используется, когда вы должны использовать ключевое слово double equals. Вы пытаетесь проверить, имеет ли объект в списке значение по сравнению с объектом за пределами списка. Обратите внимание, что, поскольку мы создали экземпляр для разных людей с именем Sam, они будут равны по стоимости, но не одному и тому же объекту.

Смежные вопросы