Object Integer mapping
NighterNet
darkneter at gmail.com
Wed Jan 20 17:01:14 EST 2010
On Jan 20, 9:43 am, Robert Kern <robert.k... at gmail.com> wrote:
> On 2010-01-20 11:18 AM, Richard Thomas wrote:
>
>
>
> > On Jan 20, 4:43 pm, NighterNet<darkne... at gmail.com> wrote:
> >> Need help on python version 3.1.x. I can't seem to know what going on
> >> a bit. The code that I check that the hash is different every time. Is
> >> there a way to make the hash the same? I using as to check the class
> >> is the same variables but if it different variable in the class that
> >> it add to the array and return the index.
>
> >> # Generic Object->Integer mapping
> >> # the object must be usable as a dictionary key
> >> class ObjMap:
> >> def __init__(self):
> >> self.dict = {}
> >> self.next = 0
> >> def get(self, obj):
> >> if obj in self.dict:
> >> return self.dict[obj]
> >> else:
> >> id = self.next
> >> self.next = self.next + 1
> >> self.dict[obj] = id
> >> return id
>
> >> def items(self):
> >> getval = operator.itemgetter(0)
> >> getkey = operator.itemgetter(1)
> >> return map(getval, sorted(self.dict.items(), key=getkey))
>
> >> class Point:
> >> def __init__(self):
> >> self.x = 0
> >> self.y = 0
> >> self.z = 0
>
> >> points = ObjMap()
>
> >> Testme = Point()
> >> Testme.x = 0
> >> print(points.get(Testme))
> >> Testme2 = Point()
> >> Testme2.y = 1
> >> print(points.get(Testme2))
> >> Testme3 = Point()
> >> Testme3.y = 1
> >> print(points.get(Testme3))
> >> Ttestme4 = Point()
> >> Ttestme4.y = 1
> >> print( points.get(Ttestme4))
>
> >> It keep adding new array from this but doesn't match hash. Need help
> >> on how to fix this class code.
>
> > You need to define how the Point class hashes. You can do this by
> > writing a __hash__ method like so:
>
> > class Point(object):
> > ...
> > def __hash__(self):
> > return hash(self.x) ^ hash(self.y) ^ hash(self.z)
>
> > However you will also need to define how the Point class relates as
> > equal using the __eq__ or __cmp__ methods.
>
> > class Point(object):
> > ...
> > def __eq__(self, other):
> > return self.x == other.x and self.y == other.y and self.z ==
> > other.z
>
> > This addition makes sure that if two points a equivalent then they
> > count as the same key in the dictionary.
>
> I recommend a simpler approach that duplicates less code and makes it easier to
> maintain the __hash__/__eq__ invariants:
>
> class Point(object):
> ...
> def _key(self):
> # The type(self).__name__ bit is optional, but usually handy.
> return (type(self).__name__, self.x, self.y, self.z)
>
> def __hash__(self):
> return hash(self._key())
>
> def __eq__(self, other):
> if not hasattr(other, '_key'):
> return False
> return self._key() == other._key()
>
> It is also worth noting that once one allows hashing by value, one should treat
> the objects as immutable, so one should not change the attributes as the OP does
> in his example.
>
> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless enigma
> that is made terrible by our own mad attempt to interpret it as though it had
> an underlying truth."
> -- Umberto Eco
Thanks you, it help fix my hash check against my classes.
More information about the Python-list
mailing list