New Python 3.0 string formatting - really necessary?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Dec 20 21:49:43 EST 2008


On Sat, 20 Dec 2008 18:23:00 -0800, r wrote:

> Answering a question with a question, that leaves me with a question of
> my own??
> 
>> Instead of just whinging, how about making a suggestion to fix it? Go
>> on, sit down for an hour or ten and try to work out how a BINARY
>> OPERATOR like % (that means it can only take TWO arguments) can deal
>> with an arbitrary number of arguments, *without* having any special
>> cases.
> 
> Instead of being a blind fanboy and chastising everyone who dares to
> question pydev, Guido, or YOU... why don't you offer a good rebuttal?

Because I thought it was obvious even you could see it. I'm disappointed 
to be proven wrong.

A binary operator can only take two arguments: one on the left, and one 
on the right:

2 + 3
5 * 7
x == 2
"%i" % 7

The typical use-case for string formatting operations requires more than 
two arguments. Since % is a binary operator, it can only take two 
arguments. One of those arguments must be the template string, so the 
other argument has to wrap all the rest of the arguments into one object:

"The %s ate %d slices of %s." % ("python", 7, "spam")

Python could have insisted that even single arguments be wrapped in a 
tuple:

"%s" % ("python",)

At the cost of breaking backwards compatibility, that would solve the 
problem of treating tuples as a special case, but it seems wasteful and 
silly to be forced to write this:

"The answer is: %d" % (5,)

instead of 

"The answer is: %d" % 5

especially when people will invariably leave out the comma and then 
complain about the "wart" or "bug" that:

"The answer is: %d" % (5)

doesn't do what they expect. So tuples are treated as a special case: you 
only need to wrap a single argument in a tuple if that argument itself is 
a tuple:

"%s" % ((0, 1, 2),)

and everything else just works as you would expect.

Again, at the cost of breaking backwards compatibility, Python could 
change the special case from tuples to something else, but what? And why 
bother? There will always be a special case, one way or another.

Consequently, there is no way to "fix" the special casing of tuples 
without just shifting the problem. The problem is fundamental to the 
nature of binary operators: you can't fit an arbitrary number of 
arguments into two places (the left hand side, and the right hand side) 
of the % operator without having to special case something.

The real solution is to stop trying to force arbitrary numbers of 
arguments into a single place, and instead use a function or method that 
takes multiple arguments. That's what the "".format() method and the 
format() function do.



-- 
Steven



More information about the Python-list mailing list