Метод __cmp__ это не работает, как ожидалось в Python 2.x? - PullRequest
6 голосов
/ 27 января 2010
class x:
    def __init__(self,name):
        self.name=name

    def __str__(self):
        return self.name

    def __cmp__(self,other):
        print("cmp method called with self="+str(self)+",other="+str(other))
        return self.name==other.name
       # return False


instance1=x("hello")
instance2=x("there")

print(instance1==instance2)
print(instance1.name==instance2.name)

Вывод здесь:

cmp method called with self=hello,other=there
True
False

Это не то, что я ожидал: я пытаюсь сказать «два экземпляра равны, если поля имени равны».

Если я просто return False из функции __cmp__, это также сообщается как True !! Если я верну -1, то получу False - но поскольку я пытаюсь сравнивать строки, это не так.

Что я здесь не так делаю?

Ответы [ 5 ]

10 голосов
/ 27 января 2010

__cmp__(x,y) должен возвращать отрицательное число (например, -1), если x < y, положительное число (например, 1), если x > y, и 0, если x == y. Вы никогда не должны возвращать логическое значение с ним.

То, что вы перегружаете, это __eq__(x, y).

5 голосов
/ 27 января 2010

метод __cmp__ должен возвращать -1, 0 или 1, когда self other уважительно.

Вы можете сделать

return cmp(self.name, other.name)

в вашем коде для правильного результата

4 голосов
/ 27 января 2010

Вы путаете __cmp__ с __eq__.

Из документации __cmp__:

Должен вернуть отрицательное целое число, еслиself other.

__eq__ возвращает логическое значение, определяющее, равны ли два объекта, __cmp__ возвращает целое число, определяющееесли два объекта больше или меньше друг друга, и поэтому вызывается, если у вас нет определенных методов __eq__, __ne__, __le__, __ge__, __lt__ и __gt__.

В вашем случае вам нужен __cmp__ метод, а не __eq__, так как это сэкономит вам реализацию 5 других методов для других сравнений.

Вы можете использовать cmp() function и добавьте в ваш метод __cmp__ следующее:

return cmp(self.name,other.name)

Примечание, , как выделено Ignacio , этот не является предпочтительным методомв Python 3.0 , но в Python 2.x __cmp__ это путь.

2 голосов
/ 27 января 2010

__cmp__() устарел. Вместо этого определите __lt__(), __eq__() и __gt__().

Несмотря на это, вы делаете это неправильно. Вы должны вернуть целое число.

0 голосов
/ 27 января 2010

Поиск документации для __cmp__, вы должны вернуть целое число:

Должно возвращать отрицательное целое число, если self other.

...