预计阅读本页时间:-
Why the New Format Method?
Now that I’ve gone to such lengths to compare and contrast the two formatting techniques, I need to explain why you might want to consider using the format method variant at times. In short, although the formatting method can sometimes require more code, it also:
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
- Has a few extra features not found in the % expression
- Can make substitution value references more explicit
- Trades an operator for an arguably more mnemonic method name
- Does not support different syntax for single and multiple substitution value cases
Although both techniques are available today and the formatting expression is still widely used, the format method might eventually subsume it. But because the choice is currently still yours to make, let’s briefly expand on some of the differences before moving on.
Extra features
The method call supports a few extras that the expression does not, such as binary type codes and (coming in Python 3.1) thousands groupings. In addition, the method call supports key and attribute references directly. As we’ve seen, though, the formatting expression can usually achieve the same effects in other ways:
>>> '{0:b}'.format((2 ** 16) −1)
'1111111111111111'
>>> '%b' % ((2 ** 16) −1)
ValueError: unsupported format character 'b' (0x62) at index 1
>>> bin((2 ** 16) −1)
'0b1111111111111111'
>>> '%s' % bin((2 ** 16) −1)[2:]
'1111111111111111'
See also the prior examples that compare dictionary-based formatting in the % expression to key and attribute references in the format method; especially in common practice, the two seem largely variations on a theme.
Explicit value references
One use case where the format method is at least debatably clearer is when there are many values to be substituted into the format string. The lister.py classes example we’ll meet in Chapter 30, for example, substitutes six items into a single string, and in this case the method’s {i} position labels seem easier to read than the expression’s %s:
'\n%s<Class %s, address %s:\n%s%s%s>\n' % (...) # Expression
'\n{0}<Class {1}, address {2}:\n{3}{4}{5}>\n'.format(...) # Method
On the other hand, using dictionary keys in % expressions can mitigate much of this difference. This is also something of a worst-case scenario for formatting complexity, and not very common in practice; more typical use cases seem largely a tossup. Moreover, in Python 3.1 (still in alpha release form as I write these words), numbering substitution values will become optional, thereby subverting this purported benefit altogether:
C:\misc> C:\Python31\python
>>> 'The {0} side {1} {2}'.format('bright', 'of', 'life')
'The bright side of life'
>>>
>>> 'The {} side {} {}'.format('bright', 'of', 'life') # Python 3.1+
'The bright side of life'
>>>
>>> 'The %s side %s %s' % ('bright', 'of', 'life')
'The bright side of life'
Using 3.1’s automatic relative numbering like this seems to negate a large part of the method’s advantage. Compare the effect on floating-point formatting, for example—the formatting expression is still more concise, and still seems less cluttered:
C:\misc> C:\Python31\python
>>> '{0:f}, {1:.2f}, {2:05.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 03.14'
>>>
>>> '{:f}, {:.2f}, {:06.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 003.14'
>>>
>>> '%f, %.2f, %06.2f' % (3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 003.14'
Method names and general arguments
Given this 3.1 auto-numbering change, the only clearly remaining potential advantages of the formatting method are that it replaces the % operator with a more mnemonic format method name and does not distinguish between single and multiple substitution values. The former may make the method appear simpler to beginners at first glance (“format” may be easier to parse than multiple “%” characters), though this is too subjective to call.
The latter difference might be more significant—with the format expression, a single value can be given by itself, but multiple values must be enclosed in a tuple:
>>> '%.2f' % 1.2345
'1.23'
>>> '%.2f %s' % (1.2345, 99)
'1.23 99'
Technically, the formatting expression accepts either a single substitution value, or a tuple of one or more items. In fact, because a single item can be given either by itself or within a tuple, a tuple to be formatted must be provided as nested tuples:
>>> '%s' % 1.23
'1.23'
>>> '%s' % (1.23,)
'1.23'
>>> '%s' % ((1.23,),)
'(1.23,)'
The formatting method, on the other hand, tightens this up by accepting general function arguments in both cases:
>>> '{0:.2f}'.format(1.2345)
'1.23'
>>> '{0:.2f} {1}'.format(1.2345, 99)
'1.23 99'
>>> '{0}'.format(1.23)
'1.23'
>>> '{0}'.format((1.23,))
'(1.23,)'
Consequently, it might be less confusing to beginners and cause fewer programming mistakes. This is still a fairly minor issue, though—if you always enclose values in a tuple and ignore the nontupled option, the expression is essentially the same as the method call here. Moreover, the method incurs an extra price in inflated code size to achieve its limited flexibility. Given that the expression has been used extensively throughout Python’s history, it’s not clear that this point justifies breaking existing code for a new tool that is so similar, as the next section argues.
Possible future deprecation?
As mentioned earlier, there is some risk that Python developers may deprecate the % expression in favor of the format method in the future. In fact, there is a note to this effect in Python 3.0’s manuals.
This has not yet occurred, of course, and both formatting techniques are fully available and reasonable to use in Python 2.6 and 3.0 (the versions of Python this book covers). Both techniques are supported in the upcoming Python 3.1 release as well, so deprecation of either seems unlikely for the foreseeable future. Moreover, because formatting expressions are used extensively in almost all existing Python code written to date, most programmers will benefit from being familiar with both techniques for many years to come.
If this deprecation ever does occur, though, you may need to recode all your % expressions as format methods, and translate those that appear in this book, in order to use a newer Python release. At the risk of editorializing here, I hope that such a change will be based upon the future common practice of actual Python programmers, not the whims of a handful of core developers—particularly given that the window for Python 3.0’s many incompatible changes is now closed. Frankly, this deprecation would seem like trading one complicated thing for another complicated thing—one that is largely equivalent to the tool it would replace! If you care about migrating to future Python releases, though, be sure to watch for developments on this front over time.