string.Template question

Peter Otten __peter__ at web.de
Mon Apr 5 22:04:10 CEST 2010


Wells Oliver wrote:

> Can you use dicts with string.Template?
> 
> e.g. a structure like:
> 
> game = {
> 'home': {'team': row['home_team_full'], 'score': row['home_score'],
> 'record': '0-0', 'pitcher': {
> 'id': home_pitcher.attrib['id'], 'name':
> home_pitcher.attrib['last_name'], 'wins': home_pitcher.attrib['wins'],
> 'losses': home_pitcher.attrib['losses']
> }, 'win': home_win}
> }
> 
> Then, in the template, 'game' is passed, but I want to access like
> $home.pitcher.id
> 
> This doesn't seem to work, though. Is it possible? Or must everything
> in the dict passed to string.Template be one-level deep string
> variables?

If you're unclear about the capabilities of a piece of python it's time to 
have a look at the source code ;)

My conclusion: you can make string.Template accept dotted variables and 
nested dicts, but not without subclassing and a few lines of custom code.

$ cat extended_template.py
import string

class DotDict(object):
    def __init__(self, d):
        self._nested = d
    def __getitem__(self, key):
        result = self._nested
        for k in key.split("."):
            result = result[k]
        return result

class Template(string.Template):
    idpattern = r'[_a-z][_a-z0-9.]*'

    def substitute(self, *args, **kw):
        assert not kw
        [d] = args
        return string.Template.substitute(self, DotDict(d))

if __name__ == "__main__":
    game = {"home": {"pitcher": {"id": 42}}}
    print Template("home/pitcher/id is $home.pitcher.id").substitute(game)

$ python extended_template.py
home/pitcher/id is 42

Peter



More information about the Python-list mailing list