I am running into an issue where I'm adding an instance to a set and then later testing to see whether or not that object exists in that set. I've overridden __eq__()
but it doesn't get called during the inclusion test. Do I have to override __hash__()
instead? If so, how would I implement __hash__()
given that I need to hash the tuple, the list, and the dictionary?
class DummyObj(object):
def __init__(self, myTuple, myList, myDictionary=None):
self.myTuple = myTuple
self.myList = myList
self.myDictionary = myDictionary
def __eq__(self, other):
return self.myTuple == other.myTuple and \
self.myList == other.myList and \
self.myDictionary == other.myDictionary
def __ne__(self, other):
return not self.__eq__(other)
if __name__ == '__main__':
list1 = [1, 2, 3]
t1 = (4, 5, 6)
d1 = { 7 : True, 8 : True, 9 : True }
p1 = DummyObj(t1, list1, d1)
mySet = set()
mySet.add(p1)
if p1 in mySet:
print "p1 in set"
else:
print "p1 not in set"
Well, my guess would be
__eq__
or__ne__
may not called by python when comparing objects using the 'in' operator. I'm not positive what the specific "rich comparison" operator would be, looking at the documentation, but overriding__cmp__
should solve your problem as python uses it by default to perform object comparisons if a more suitable "rich comparison" operator is not implemented.From the documentation on sets:
The __hash__ function documentation suggests xor-ing the hashes of components together. As others have mentioned, it's generally not a good idea to hash mutable objects, but if you really need to, this works:
And checking to see if it works:
This prints: