string formatting with mapping & '*'... is this a bug?

Alex Martelli aleaxit at
Fri Sep 10 13:31:09 CEST 2004

Pierre Fortin <pfortin at> wrote:
> def mkdict(**kwargs):
>     return kwargs

You don't need this with Python 2.3 and later -- just call dict with
keyword args, it just works!-)

> fmt = { 'wDate':10, 'wOpen':6, 'wHigh':6, 'wLow':6,  # width

...and you don't use the keyword form here, which WOULD be nice;-).

>     # line continuations must be left-justified to avoid extra spaces

nope, you can format as you wish, thanks to Python's handy idea
(mutuated from C) of merging logically adjacent literals:

>     print "%%(Date)%(wDate)d.%(pDate)ds \
> %%(Open)%(wOpen)d.%(pOpen)df \

You could use, say:

     print (  "%%(Date)%(wDate)d.%(pDate)ds"
                 " %%(Open)%(wOpen)d.%(pOpen)df "
                 etc etc

Anyway, your solution is neat but it seems a bit repetitive to me.  Any
time you have to type the same thing right over and over, aka
"boilerplate", there is a reduction in clarity and legibility and a risk
of typos.  I would therefore suggest a more advanced idea...:

class formatter:
    def __init__(self, format_map, default_width=6, default_prec=2):
    def __getitem__(self, varname):
        return '%%(%s)%d.%d" % (varname,
            self.format_map.get('w'+varname, self.default_width),
            self.format_map.get('p'+varname, self.default_prec))

now you can modify your code to do
    fmt = formatter(fmt)
[[you can actually simplify your fmt dict a lot thanks to the
defaults]], and then code the printing like:

print ( '%(Date)ss %(Open)sf %(High)sf %(Low)sf %%(Change)s' 
          % fmt % map )

It seems to me that this is more readable and easier to maintain than
the repetitious style that you need if fmt is a plain dictionary.

The real point here is that the RHS operand of % can be ANY mapping:
code your own __getitem__ and make it return whatever computed result is
most convenient to you.


More information about the Python-list mailing list