views:

89

answers:

2

I create the following class:

class Image(object):
    def __init__(self, extension, data, urls=None, user_data=None):
        self._extension = extension
        self._data = data
        self._urls = urls
        self._user_data = user_data
        self._hex_digest = hashlib.sha1(self._data).hexDigest()

Images should be equal when all values are equal. Therefore I wrote:

    def __eq__(self, other):
        if isinstance(other, Image) and self.__dict__ == other.__dict__:
            return True
        return False

    def __ne__(self, other):
        return not self.__eq__(other)

    def __lt__(self, other):
        return self.__dict__ < other.__dict__
    ...

But how should the __hash__ method look like? Equal Images should return equal hashes...

    def __hash__(self):
        # won't work !?!  
        return hash(self.__dict__)

Is the way I try to use __eq__, __ne__, __lt__, __hash__, ... recommend?

+5  A: 

Do you really need the images to be ordered? If not, I would drop the __lt__ method. For __hash__, remember that two unequal objects can have the same hash value, so you can just pick one of your attributes (or use a tuple of multiple attributes) to derive the hash code. Ex:

def __hash__(self):
    return hash(self._hex_digest)
Geoff Reedy
I though for a consitent class I have to overload `__eq__, __ne__, __lt__, __le__, __ge__, __gt__, ...` instead of `__cmp__`.
Marten Bauer
+1  A: 

Have you looked the rules for dictionary comparison?

Check here: http://docs.python.org/reference/expressions.html#notin

This is not well-defined (yet). It may be defined in a "What's New" document.

However, small tests seem to indicate that this is workable.

>>> a= { 'a':1, 'b':2 }
>>> b= { 'a':2, 'b':2 }
>>> a == a
True
>>> a == b
False
>>> a < b
True
>>> a > b
False
>>> a >= b
False
S.Lott