__all__ = [ 'multidict' ] class multidict(object): __nodefault = object() def __init__(self, parent = {}, **kwargs): self.dict = dict(**kwargs) self.parent = parent self.deleted = {} def __str__(self): return str(dict(self.items())) def __repr__(self): return `dict(self.items())` def __contains__(self, key): return self.dict.has_key(key) or self.parent.has_key(key) def __delitem__(self, key): try: del self.dict[key] except KeyError, e: if key in self.parent: self.deleted[key] = True else: raise KeyError, e def __setitem__(self, key, value): self.deleted.pop(key, False) self.dict[key] = value def __getitem__(self, key): try: return self.dict[key] except KeyError, e: if not self.deleted.get(key, False) and key in self.parent: return self.parent[key] else: raise KeyError, e def __len__(self): return len(self.dict) + len(self.parent) def next(self): for key,value in self.dict.items(): yield key,value if self.parent: for key,value in self.parent.next(): if key not in self.dict and key not in self.deleted: yield key,value def has_key(self, key): return key in self def iteritems(self): for item in self.next(): yield item def items(self): return [ item for item in self.next() ] def iterkeys(self): for key,value in self.next(): yield key def keys(self): return [ key for key,value in self.next() ] def itervalues(self): for key,value in self.next(): yield value def values(self): return [ value for key,value in self.next() ] def get(self, key, default=__nodefault): try: return self[key] except KeyError, e: if default != self.__nodefault: return default else: raise KeyError, e def setdefault(self, key, default): try: return self[key] except KeyError: self.deleted.pop(key, False) self.dict[key] = default return default def _dump(self): print 'multidict dump' node = self while isinstance(node, multidict): print ' ', node.dict node = node.parent def _dumpkey(self, key): values = [] node = self while isinstance(node, multidict): if key in node.dict: values.append(node.dict[key]) node = node.parent print key, values if __name__ == '__main__': test1 = multidict() test2 = multidict(test1) test3 = multidict(test2) test4 = multidict(test3) test1['a'] = 'test1_a' test1['b'] = 'test1_b' test1['c'] = 'test1_c' test1['d'] = 'test1_d' test1['e'] = 'test1_e' test2['a'] = 'test2_a' del test2['b'] test2['c'] = 'test2_c' del test1['a'] test2.setdefault('f', multidict) print 'test1>', test1.items() print 'test2>', test2.items() #print test1['a'] print test1['b'] print test1['c'] print test1['d'] print test1['e'] print test2['a'] #print test2['b'] print test2['c'] print test2['d'] print test2['e'] for key in test2.iterkeys(): print key test2.get('g', 'foo') #test2.get('b') test2.get('b', 'bar') test2.setdefault('b', 'blah') print test1 print test2 print `test2` print len(test2) test3['a'] = [ 0, 1, 2, 3 ] print test4