Nested Mapping

Peter Otten __peter__ at web.de
Fri Oct 22 13:17:42 CEST 2010


Raymond Hettinger wrote:

> I'm considering a nested mapping class for the collections module and
> would like to solicit feedback from people here on comp.lang.python:
> 
>    http://code.activestate.com/recipes/577434-nested-contexts-a-chain-of-
mapping-objects/
> 
> The class is an attempt to generalize from existing use cases (i.e.
> the _multimap class in string.py).  I also took guidance from the
> symbol table analysis tools in ANTLR (see p.173 of Language
> Implementation Patterns by Terence Parr).  Nested mappings make it
> easy to build chains and trees of scopes (like vocabularies in Forth
> or like inheritance hierarchies in Python).
> 
> The basic idea is to perform look-ups into a series a dictionaries,
> much like Python does with locals, nested scopes, global (module
> level) scope and builtins.
> 
> Starting with a root context which has a full dictionary API, multiple
> child contexts can be created.  New values are stored in the child
> contexts, potentially masking those in a parent context (much like
> shadowing a Python builltin).  Lookups start with the child node and
> work upward through the chain of parents.
> 
> There is also a variant where __setitem__ and __delitem__ can mutate
> values in parent contexts (much like the nonlocal keyword allows in
> Python).
> 
> The API seeks to fully emulate regular dictionaries.  The only extra
> capabilities are:
> 
>    d = c.new_child()    # create a subcontext
>    e = d.new_child()    # create a subsubcontext
>    e.parent                 # find the next enclosing context
>    e.root                     # find the outermost enclosing context
>    f = c.new_child()     # create a subcontext of c, independent of d
> & e
> 
> I would appreciate any feedback on the API and on how well it fits
> with various use cases that you've found in the wild.

I just read the recipe, and it looks good to me except for the len() and 
iter() implementations:

>>> a = Context()
>>> a["x"] = 1
>>> b = a.new_child()
>>> b["x"] = 2
>>> len(b)
2
>>> b.keys()
['x', 'x']

I would have expected equal keys to occur/count just once.

Peter



More information about the Python-list mailing list