[Python-Dev] proposal: evaluated string

Raymond Hettinger rhettinger at ewtllc.com
Thu Apr 20 19:58:28 CEST 2006


tomer filiba wrote:

> many times, templating a string is a tidious task. using the % 
> operator, either with tuples or dicts,
> is difficult to maintain, when the number of templated arguments is 
> large. and string.Template,
> although more easy to read, is less intutive and cumbersome:
>
> import string
> t = string.Template("hello $name")
> print t.substitute({"name" : "john"})

Using the key twice is basic to templating (once of specify where to 
make the substitution and once to specify its value).  This is no 
different from using variable names in regular code:   a=1; ... ; b = 
a+2  # variable-a is used twice.

Also, the example is misleading because real-apps are substitute 
variables, not constants.  IOW, the above code fragment is sematically 
equivalent to:  print "hello john".

> i'm suggesting something like boo's string interpolation: 
> http://boo.codehaus.org/String+Interpolation

We already have a slew of templating utilities (see Cheetah for example).


> but i chose to call it "evaluated string".
>
> like raw strings (r""), which are baiscally a syntactic sugar, 
> evaluated strings will be marked by 'e',
> for instance, e"", which may be combined with the 'r' or 'u', that 
> exist today.
>
> the evaluated string will be evaluated based on the current scope 
> (locals and globals), just like
> normal expressions. the difference is, the results of the expressions 
> will be str()ed into the
> evaluated string directly. these expressions will be embedded into the 
> string surrounded by
> special delimiters, and an unclosed delimited or a syntax error will 
> be reported at just like "\x??"
> raises "ValueError: invalid \x escape".
>
> i'm not sure which delimiters to use, but i think only { } is 
> sufficient (no need for ${ } like in boo)
>
> some examples:
> ===============
> name = "john"
> print e"hello {name}"


The string.Template() tool already does this right out of the box:

 >>> print Template('hello $name').substitute(globals())
hello john

So, essentially the proposal is to make the globals() access implicit 
and to abbreviate the Template constructor with new syntax.  The latter 
is not desirable because 1) it is less readable, 2) string prefixing is 
already out-of-control (used for raw strings and unicode), 3) it is less 
flexible than  the class constructor which can be subclassed and 
extended as needed.

If you don't like the $name style of template markup and prefer 
delimiters instead, then check-out the recipe at:

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/3053


> a = 3
> b = 7
> print e"the function is y = {a}x + {b}"
> for x in range(10):
>     print e"y({x}) = {a*x+b}"
>
> import time, sys
> print e"the time is {time.asctime()} and you are running on { 
> sys.platform}


If you need this, then consider using a third-party templating module.  
Be sure to stay aware of the security risks if the fill-in values are 
user specified.




Raymond


More information about the Python-Dev mailing list