1

I was reading this post and I had a question regarding __cmp__().

My code

class Book(object): 

    def __init__(self, title, year):

        self.title = title
        self.year = year

    def __hash__(self):         # hash function

        print "Self = ", self
        print "Hash value of self = ", hash(str(self))
        print "Hash value of title = ", hash(self.title)
        print "Hash value of year = ", hash(self.year)
        return 0
    def __cmp__(self, other):
        return self.title == other.title

books = []

books.append(Book("ABC", 123))
print hash(books[0])

books.append(Book("DEF", 456))
print hash(books[1])


books.append(Book("ABC", 123))
print hash(books[len(books)-1])

print len(books)

print cmp(books[0],books[2])

Output

Self =  <__main__.Book object at 0x0000000001E77B00>
Hash value of self =  -1040857764
Hash value of title =  826005955
Hash value of year =  123
0
Self =  <__main__.Book object at 0x0000000001E77BA8>
Hash value of self =  -992414627
Hash value of title =  -589261154
Hash value of year =  456
0
Self =  <__main__.Book object at 0x0000000001E77BE0>
Hash value of self =  1901105233
Hash value of title =  -2015893559
Hash value of year =  789
0
Self =  <__main__.Book object at 0x0000000001E77C18>
Hash value of self =  -228580758
Hash value of title =  826005955
Hash value of year =  123
0
4
1  # How ? 

== operator on strings returns a Boolean value.
In this code the cmp() compares two strings (namely the titles) so the return value of the cmp() must be a Bool.

  • How come I am getting an integer ? (I am looking for an explanation with respect to the comparison of objects x > y)
  • Even when an integer is obtained, how is its value decided ?
  • How can I make the 1st and the 3rd object equal ?
Community
  • 1
  • 1
Kshitij Saraogi
  • 6,821
  • 8
  • 41
  • 71

1 Answers1

1

How come I am getting an integer ?

__cmp__ returns an int. Your __cmp__ is returning a bool, which is a subclass of int, so Python interprets it as an int.

Even when an integer is obtained, how is its value decided ?

  • -1 means the first operand is less than the second
  • 0 means both operands are equal
  • +1 means the first operand is greater than the second

How can I make the 1st and the 3rd object equal?

The problem with your code is your __cmp__ returns the result of ==, which returns a bool, which is a subclass of int, and True is 1, so instead of returning 0 your __cmp__ is returning True/1 -- which is wrong.

The methods you should be using (as __cmp__ gets removed in later Pythons) are __eq__, __ne__, __le__, __lt__, __ge__, and __gt__.

Using __eq__:

def __eq__(self, other):
    if not isinstance(other, self.__class__):
        return NotImplemented
    return self.title == other.title

Note that this is only comparing by title, and not considering the year (which may be fine, or may not be, depending on how you will be using your Book class).

You can find out more about them here.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237