On Thu, Oct 15, 2009 at 5:22 AM, Diez B. Roggisch <de...@nospam.web.de> wrote: > Chris Rebert wrote: > >> On Thu, Oct 15, 2009 at 4:24 AM, Austin Bingham >> <austin.bing...@gmail.com> wrote: >>> If I understand things correctly, the set class uses hash() >>> universally to calculate hash values for its elements. Is there a >>> standard way to have set use a different function? Say I've got a >>> collection of objects with names. I'd like to create a set of these >>> objects where the hashing is done on these names. Using the __hash__ >>> function seems inelegant because it means I have to settle on one type >>> of hashing for these objects all of the time, i.e. I can't create a >>> set of them based on a different uniqueness criteria later. I'd like >>> to create a set instance that uses, say, 'hash(x.name)' rather than >>> 'hash(x)'. >>> >>> Is this possible? Am I just thinking about this problem the wrong way? >>> Admittedly, I'm coming at this from a C++/STL perspective, so perhaps >>> I'm just missing the obvious. Thanks for any help on this. >> >> You could use wrapper objects that define an appropriate __hash__(): >> >> #*completely untested* >> class HashWrapper(object): >> def __init__(self, obj, criteria): >> self._wrapee = obj >> self._criteria = criteria >> >> #override __hash__() / hash() >> def __hash__(self): >> return hash(self._criteria(self._wrapee)) >> >> #proxying code >> def __getattr__(self, name): >> return getattr(self._wrapee, name) >> >> def __setattr__(self, name, val): >> setattr(self._wrapee, name, val) > > This doesn't work for conflicting elements, as the __eq__-method isn't > overriden.
Indeed. Good catch. :) This is why I mark code as "completely untested". Cheers, Chris -- http://mail.python.org/mailman/listinfo/python-list