String formatters with variable argument length

John Machin sjmachin at lexicon.net
Fri Dec 1 14:03:01 EST 2006


Peter Otten wrote:
> John Machin wrote:
>
> >> > Fredrik Tolf wrote:
>
> >> > > The thing is, I want to get format strings from the user, and I don't
> >> > > want to require the user to consume all the arguments.
>
> > what's ugly about this:
> > [untested]:
> >
> > def count_format_args(s):
> >     pending = False
> >     count = 0
> >     for c in s:
> >         if c == "%":
> >             # doubled % chars aren't counted
> >             pending = not pending
> >         elif pending:
> >             count += 1
> >             pending = False
> >     return count
> >
> > output = format % arglist[:count_format_args(format)]
>
> Keep in mind, though, that it doesn't take '*' into account:
>
> >>> count_format_args("%*.*f")
> 1
> >>> "%*.*f" % (3,2,1)
> '1.00'

A good point. Adding checking for "*" would make it rather ugly, as "*"
is special only inside a conversion specifier.

>
> And just because I don't think I've seen it before:
>
> >>> count_format_args("%42%")
> 1
> >>> "%42%" % ()
> '                                         %'

Hmmm ... I hadn't seen that before either. I would have said if shown
that input that I could have put in an error check that pending was not
true at the end of the loop, but was relying instead on an exception
from the formatting operator.

Even better: >>> "%-42%" % ()
 '%                                         '

:-)
Before gentle readers consider nominating the Python core dev team to
thedailyWTF.com, they might wish to:
(1) read the Python documentation
(http://docs.python.org/lib/typesseq-strings.html)
[it is not a simple escape mechanism; the second % is a "conversion
type"]
(2) compare those docs carefully with K&R v2 section B1.2 Formatted
Output (pp 243-245)
(3) note that not everything that emanated from Murray Hill NJ obeyed
the Law of Least Astonishment
:-)

Cheers,
John




More information about the Python-list mailing list