Skip to content

Instantly share code, notes, and snippets.

@kurtbrose
Created June 26, 2012 17:44
Show Gist options
  • Save kurtbrose/2997384 to your computer and use it in GitHub Desktop.
Save kurtbrose/2997384 to your computer and use it in GitHub Desktop.
chaining dictionary
class updict(dict):
def __new__(cls, up=None, *a, **kw):
return dict.__new__(cls, *a, **kw)
def __init__(self, up=None, *a, **kw):
dict.__init__(self, *a, **kw)
self.up = up
def mro(self):
def mro_gen():
cur = self
while cur:
yield cur
cur = cur.up
return mro_gen()
@property
def up(self):
return self._up
@up.setter
def up(self, up):
if up is not None and self in up.mro():
raise ValueError("circular updict")
self._up = up
def __missing__(self, key):
if self._up is None: #skip property for internal reference
raise KeyError(key)
return self._up[key]
class updict(dict):
'''
A dictionary that will look "up" to a parent mapping when a key is not found.
Can be used to simulate lexical scoping or inheritance.
'''
def __new__(cls, up=None, *a, **kw):
return dict.__new__(cls, *a, **kw)
def __init__(self, up=None, *a, **kw):
dict.__init__(self, *a, **kw)
self.up = up
def __missing__(self, key):
if self.up is None:
raise KeyError(key)
return self._get_up(key, set())
def _get_up(self, key, sofar):
if id(self) in sofar:
raise KeyError(key)
sofar.add(id(self))
if key in self:
return self[key]
return self.up._get_up(key, sofar)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment