1"""Misc dict tools.""" 2 3 4__all__ = ['hashdict'] 5 6# https://stackoverflow.com/questions/1151658/python-hashable-dicts 7class hashdict(dict): 8 """ 9 hashable dict implementation, suitable for use as a key into 10 other dicts. 11 12 >>> h1 = hashdict({"apples": 1, "bananas":2}) 13 >>> h2 = hashdict({"bananas": 3, "mangoes": 5}) 14 >>> h1+h2 15 hashdict(apples=1, bananas=3, mangoes=5) 16 >>> d1 = {} 17 >>> d1[h1] = "salad" 18 >>> d1[h1] 19 'salad' 20 >>> d1[h2] 21 Traceback (most recent call last): 22 ... 23 KeyError: hashdict(bananas=3, mangoes=5) 24 25 based on answers from 26 http://stackoverflow.com/questions/1151658/python-hashable-dicts 27 28 """ 29 def __key(self): 30 return tuple(sorted(self.items())) 31 def __repr__(self): 32 return "{0}({1})".format(self.__class__.__name__, 33 ", ".join("{0}={1}".format( 34 str(i[0]),repr(i[1])) for i in self.__key())) 35 36 def __hash__(self): 37 return hash(self.__key()) 38 def __setitem__(self, key, value): 39 raise TypeError("{0} does not support item assignment" 40 .format(self.__class__.__name__)) 41 def __delitem__(self, key): 42 raise TypeError("{0} does not support item assignment" 43 .format(self.__class__.__name__)) 44 def clear(self): 45 raise TypeError("{0} does not support item assignment" 46 .format(self.__class__.__name__)) 47 def pop(self, *args, **kwargs): 48 raise TypeError("{0} does not support item assignment" 49 .format(self.__class__.__name__)) 50 def popitem(self, *args, **kwargs): 51 raise TypeError("{0} does not support item assignment" 52 .format(self.__class__.__name__)) 53 def setdefault(self, *args, **kwargs): 54 raise TypeError("{0} does not support item assignment" 55 .format(self.__class__.__name__)) 56 def update(self, *args, **kwargs): 57 raise TypeError("{0} does not support item assignment" 58 .format(self.__class__.__name__)) 59 # update is not ok because it mutates the object 60 # __add__ is ok because it creates a new object 61 # while the new object is under construction, it's ok to mutate it 62 def __add__(self, right): 63 result = hashdict(self) 64 dict.update(result, right) 65 return result 66 67