yet another recipe on string interpolation

Raymond Hettinger vze4rx4y at verizon.net
Sat Nov 6 23:11:16 EST 2004


"Michele Simionato":
> I was playing with string.Template in Python 2.4 and I came out with the
> following recipe:
>
> import sys
> from string import Template
>
> def merge(*dictionaries):
>     """Merge from right (i.e. the rightmost dictionary has the precedence)."""
>     merg = {}
>     for d in dictionaries:
>         merg.update(d)
>     return merg
>
> def interp(s, dic = None):
>     if dic is None: dic = {}
>     caller = sys._getframe(1)
>     return Template(s) % merge(caller.f_globals, caller.f_locals, dic)

The ASPN chainmap() recipe is an alternative to merge().  It spares the initial
effort of combining all the dictionaries.  Instead, it does the lookups only
when a specific key is needed.  In your example, it is likely that most of
globals will never be looked-up by the template, so the just-in-time approach
will save time and space.  Also, chainmap() is a bit more general and will work
with any object defining __getitem__.

The interp() part of the recipe is nice.


Raymond Hettinger


http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305268 :
--------- chainmap() ---------


import UserDict

class Chainmap(UserDict.DictMixin):
    """Combine multiple mappings for sequential lookup.

    For example, to emulate Python's normal lookup sequence:

        import __builtin__
        pylookup = Chainmap(locals(), globals(), vars(__builtin__))
    """

    def __init__(self, *maps):
        self._maps = maps

    def __getitem__(self, key):
        for mapping in self._maps:
            try:
                return mapping[key]
            except KeyError:
                pass
        raise KeyError(key)


Raymond Hettinger





More information about the Python-list mailing list