yet another recipe on string interpolation
Peter Otten
__peter__ at web.de
Thu Nov 4 13:39:04 EST 2004
Michele Simionato wrote:
> 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)
>
> language="Python"
> print interp("My favorite language is $language.")
>
> Do you have any comments? Suggestions for improvements?
Nice. recipe. I think the perlish format looks better than our current
"%(name)s" thingy. While interp() does some magic it should still be
acceptable for its similarity with eval(). Here are some ideas:
You could virtualize the merger of dictionaries:
class merge(object):
def __init__(self, *dicts):
self.dicts = dicts
def __getitem__(self, key):
for d in reversed(self.dicts):
try:
return d[key]
except KeyError:
pass
raise KeyError(key)
I would use either implicitly or explicitly specified dictionaries, not
both:
def interp(s, *dicts, **kw):
if not dicts:
caller = sys._getframe(1)
dicts = (caller.f_globals, caller.f_locals)
return Template(s).substitute(merge(*dicts), **kw)
As of 2.4b2, the modulo operator is not (not yet, or no longer?) defined, so
I had to use substitute() instead.
I really like your option to provide multiple dictionaries - maybe you
should suggest changing the signature of the substitute() method to the
author of the Template class.
Peter
More information about the Python-list
mailing list