[Python-Dev] converting the stdlib to str.format

Nick Coghlan ncoghlan at gmail.com
Wed Jun 4 15:28:40 CEST 2008

Antoine Pitrou wrote:
> Michael Foord <fuzzyman <at> voidspace.org.uk> writes:
>> Simple string formatting with %s and a single object or a tuple meets 
>>  >90% of my string formatting needs.
> Not to mention that e.g. "%r" % s is much simpler than "{0!r}".format(s)
> (if I got the format spec right).

repr(s) is even simpler :)

The basic idea for conversions to the new formatting:

'%r' % v --> repr(v) # or ascii(v) if more appropriate
'%s' % v --> str(v) # or format(v), or format(v, '')

The str/unicode stability that the latter provided in 2.x is no longer 
needed in 3.x. The first one never had any advantage that I can see over 
invoking repr() directly (since repr() and %r always produce an 8-bit 
string in 2.x)

The conversion of fmt % v depends on both fmt and v:

v is a single value, fmt is only a formatting code:
   '%x' % v--> format(v, 'x')

v is a single value, fmt is both a formatting code and additional text:
   'Value: %x' % v--> 'Value: {0:x}'.format(v)
Note that the old code in this case wouldn't display dict or tuple 
instances correctly. Avoiding that ambiguity is a major advantage of the 
new approach.

v is a tuple* (more on this below):
   'Key: %s Value: %s' % k, v --> 'Key: {0} Value: {1}'.format(k, v)

fmt uses named parameters:
   'Value: %(val)s' % dict(val=v) --> 'Value: {val}'.format(val=v)

* I still think the new str.format approach is too verbose and requires 
too much thought for simple use cases where the printf-style % 
replacement hits a sweet spot between being easy to write and easy to read.

So I see the introduction of str.format in 3.0 as an opportunity to 
*fix* %-formatting later in the 3.x series rather than get rid of it 
entirely. The fixes I would apply:

- remove support for %(name)s based formatting (str.format is vastly 
superior once you start naming the parameters).

- remove support for passing a single value to a format string without 
wrapping it in an iterable first

- accept any iterable as the right hand argument str.__mod__

This approach would eliminate the current ambiguity in fmt.v, and would 
allow fmt % [x] to be used to box an argument for safe use in a 
single-parameter format string instead of having to muck around with 
singleton tuples.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-Dev mailing list