I have to merge two dictionaries into one, and in a "shallow" way: changing items should be possible by operating either on two parents or on a new dictionary. I am open to suggestions how to do this (values are always numbers, BTW), but I tried to do it by creating a dict-like class that just forwards all calls to the two parent dicts, see below.
It works, but one important thing is missing. I am not able to expand new dictionary with double-star operator ** to use it as a set of keyword arguments of a function. I googled a bit, but was unable to find what property must an object have to be correctly treated by **. I hope the following code is self-explanatory: ------------------------------------ import itertools class hubDict(dict): """Merges two dictionaries, but not actually but just by forwarding.""" def __init__(self, da, db): self.d1 = da self.d2 = db def __getitem__(self, name): if self.d1.has_key(name): return self.d1[name] else: return self.d2[name] def __setitem__(self, name, value): if self.d1.has_key(name): self.d1[name] = value else: self.d2[name] = value def __iter__(self): return itertools.chain(self.d1.__iter__(), self.d2.__iter__()) def has_key(self, name): if self.d1.has_key(name) or self.d2.has_key(name): return True else: return False def keys(self): return self.d1.keys() + self.d2.keys() def items(self): return self.d1.items() + self.d2.items() def iteritems(self): return itertools.chain(self.d1.iteritems(), self.d2.iteritems()) def iterkeys(self): return itertools.chain(self.d1.iterkeys(), self.d2.iterkeys()) def itervalues(self): return itertools.chain(self.d1.itervalues(), self.d2.itervalues()) def copy(self): print "Can't copy hubDict yet!!!" def update(self, d): for key in d: self.__setitem__(key, d[key]) def popitem(self): try: return self.d1.popitem() except KeyError: return self.d2.popitem() def __repr__(self): return 'First: %s\nSecond: %s' % ( self.d1.__repr__(), self.d2.__repr__()) # Trying it now: da = {'a':1} db = {'b':2} dh = hubDict(da, db) def kwa(**kwargs): print kwargs #OK kwa(**da) #not OK: prints empty dict kwa(**dh) import itertools class hubDict(dict): """Merges two dictionaries, but not actually but just by forwarding.""" def __init__(self, da, db): self.d1 = da self.d2 = db def __getitem__(self, name): if self.d1.has_key(name): return self.d1[name] else: return self.d2[name] def __setitem__(self, name, value): if self.d1.has_key(name): self.d1[name] = value else: self.d2[name] = value def __iter__(self): return itertools.chain(self.d1.__iter__(), self.d2.__iter__()) def has_key(self, name): if self.d1.has_key(name) or self.d2.has_key(name): return True else: return False def keys(self): return self.d1.keys() + self.d2.keys() def items(self): return self.d1.items() + self.d2.items() def iteritems(self): return itertools.chain(self.d1.iteritems(), self.d2.iteritems()) def iterkeys(self): return itertools.chain(self.d1.iterkeys(), self.d2.iterkeys()) def itervalues(self): return itertools.chain(self.d1.itervalues(), self.d2.itervalues()) def copy(self): print "Can't copy hubDict yet!!!" def update(self, d): for key in d: self.__setitem__(key, d[key]) def popitem(self): try: return self.d1.popitem() except KeyError: return self.d2.popitem() def __repr__(self): return 'First: %s\nSecond: %s' % ( self.d1.__repr__(), self.d2.__repr__()) def __len__(self): return self.d1.__len__() + self.d2.__len__() # Trying it now: da = {'a':1} db = {'b':2} dh = hubDict(da, db) def kwa(**kwargs): print kwargs #OK kwa(**da) #not OK: prints empty dict kwa(**dh) -- http://mail.python.org/mailman/listinfo/python-list