[Python-Dev] string.Template format enhancements (Re: Replacement for print in Python 3.0)
Nick Coghlan
ncoghlan at gmail.com
Tue Sep 6 16:07:01 CEST 2005
tanzer at swing.co.at wrote:
> Positional arguments remove too much meaning from the template.
>
> Compare:
>
> '$user forgot to frobnicate the $file!\n'
>
> with
>
> '$1 forgot to frobnicate the $2!\n'
>
> Whenever the template definition and its use are not directly
> adjacent, the template is that much harder to understand (i.e.,
> in the context of translation, one wouldn't see the arguments
> passed to the template).
Ideas like this one are really about taking the current C-originated string
formatting and replacing it with a more powerful version of the new
string.Template formatting.
One interesting idea to consider is to add "format" and "safe_format" string
methods (or "substitute" and "safe_substitute" if matching the PEP 292 method
names is considered important) which work something like:
# These would be new str and unicode methods
def format(*args, **kwds):
return string.Template(args[0]).substitute(*args[1:], **kwds)
def safe_format(*args, **kwds):
return string.Template(args[0]).safe_substitute(*args[1:], **kwds)
Then enhance string.Template such that:
1. Item identifiers could be numbers as well as valid Python identifiers
2. Positional arguments were added to the dictionary of items using their
argument index as a string
Something like:
# This would be modified behaviour of the substitute method
# rather than a separate method or function
def pos_substitute(*args, **kwds):
self = args[0]
kwds.update((str(idx), arg) for idx, arg in enumerate(args))
# Avoiding including self in kwds is also an option
return self.substitute(**kwds)
(To try this on Py2.4, use "$p1" for the positional arguments to easily get
around the restriction in the string.Template regex)
With the above changes, the following would work:
"$1: $2".format("Number of bees", "0.5")
And produce:
"Number of bees: 0.5"
When pre-compiling string.Templates, the keyword method is significantly
clearer, but if the syntax was accessible through a string method, then being
able to use positional arguments would be very handy.
At this point, the only thing missing is the ability to handle proper output
formatting - that would need to be done by invoking the string mod operator
directly on the positional argument via:
"$1: $2".format("Number of bees: ", "%0.2f" % val)
In theory (I haven't really tried this bit), it should be possible to adjust
string.Template to support the following equivalent:
"$1: $[0.2f]2".format("Number of bees: ", val)
That way, rather than inventing a new formatting language, string.Template
could leverage the existing string mod operator by substituting the result of
"('%' + fmt) % val" wherever it sees "$[fmt]name" or "$[fmt]{name}"
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list