[Python-Dev] PEP 292, Simpler String Substitutions

Duncan Booth duncan@rcp.co.uk
Wed, 19 Jun 2002 10:34:24 +0100


On 19 Jun 2002, Martin Sjögren <martin@strakt.com> wrote:

> But what about
> 
>>>> '%(name)s was born in %(country)s' % {'name':'Guido',
>   'country':'the Netherlands'}
> 'Guido was born in the Netherlands'
>>>> name = 'Martin'
>>>> country = 'Sweden'
>>>> '%(name)s was born in %(country)s' % globals()
> 'Martin was born in Sweden'
> 
> What's the advantage of using ${name} and ${country} instead?

Presumably it looks more natural to people experienced in shell programming 
or Perl---at the expense of losing the ability to format field widths and 
alignments of course (so should we have regexes delimited by '/' next?). 
Personally I can't see the need for a second form of string interpolation, 
but since it comes up so often somebody must feel it is significantly 
superior to the existing system.

What I really don't understand is why there is such pressure to get an 
alternative interpolation added as methods to str & unicode rather than 
just adding an interpolation module to the library?
e.g.

from interpolation import sub
def birth(self, name):
    country = self.countryOfOrigin['name']
    return sub('${name} was born in ${country}', vars())

I added in the explicit vars() parameter because the idea of a possibly 
unknown template string picking up arbitrary variables is, IMHO, a BAD 
idea.

If it were a library module then it would probably also make sense to 
define a wrapper object constructed from a sequence that would do the 
interpolation when called:
e.g.
>>> message = interpolation.template('${name} was born in ${country}')
>>> print message(name='Duncan', country='Scotland')
Duncan was born in Scotland 

Putting it in a separate module would also give more scope for providing 
minor variations on the theme, for example the default should be to throw a 
NameError for missing variables, but you could have another function 
wrapping the basic one that substituted in a default value instead.

-- 
Duncan Booth                                             duncan@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?