Python必懂知识点,格式化字符串,到底用.format还是%

第一次听说格式化,是清理电脑磁盘时,以为格式化就是清空一切,重回自由,后来才知道,格式化,是另一种妥协。

Python必懂知识点,格式化字符串,到底用.format还是%


以下部分节选自《编写高质量代码:改善Python程序的91个建议》一书,需要该书电子版的可以私我。


第一部分:%操作符

%操作符根据转换说明符所规定的格式返回一串格式化后的字符串,转换说明符的基本形式为:

%[转换标记][宽度[.精确度]]转换类型

其中常见的转换标记和转换类型分别如图1和图2所示。如果未指定宽度,则默认输出为字符串本身的宽度。

Python必懂知识点,格式化字符串,到底用.format还是%

图1 格式化字符串转换标记


Python必懂知识点,格式化字符串,到底用.format还是%

图2 格式化字符串转换类型

%操作符格式化字符串时常见用法:

1)直接格式化字符或者数值。

<code>print('your sorce is %06.1f' % 9.5)
# your sorce is 0009.5/<code>


2)以元组的形式格式化。

<code>import math
item_name = 'circumference'
radius = 3
print('the %s of a circle with radius %f is %0.3f' % (item_name, radius, math.pi*radius*2))
# the circumference of a circle with radius 3.000000 is 18.850/<code>


3)以字典的形式格式化。

<code>item_dict = {'itemname': 'circumference', 'radius': 3, 'value': math.pi*radius*2}
print('the %(itemname)s of a circle with radius %(radius)f is %(value)0.3f' % item_dict)
# the circumference of a circle with radius 3.000000 is 18.850/<code>


第二部分:.format方法

.format方式格式化字符串的基本语法:

[[填充符]对齐方式][符号][#][0][宽度][,][.精确度][转换类型]。

其中填充符可以是除了“{”和“}”符号之外的任意符号,对齐方式和符号分别如图3和图4所示。转换类型跟%操作符的转换类型类似,可以参见图2。


Python必懂知识点,格式化字符串,到底用.format还是%

图3 .format方式格式化字符串的对齐方式

Python必懂知识点,格式化字符串,到底用.format还是%

图4 .format方式格式化字符串符号列表


.format方法几种常见的用法如下:

1)使用位置符号。

<code>print('The number {0:,} in hex is: {0: #x}, the number {1} in oct is {1:#o}'.format(4746,45))
# The number 4,746 in hex is:  0x128a, the number 45 in oct is 0o55/<code>

其中{0}表示forma方法中对应的第一个参数,{1}表示format方法对应的第二个参数,依次递推


2)使用名称。

<code>print('the max number is {max}, the min number is {min}, the average number is {average:0.3f}'.format(max=189, min=12.6, average=23.5))
# the max number is 189, the min number is 12.6, the average number is 23.500/<code>


3)通过属性。

<code>class Customer(object):
    def __init__(self, name, gender, phone):
        self.name = name
        self.gender = gender
        self.phone = phone
    # 通过str()函数返回格式化的结果
    def __str__(self):
        return 'Customer({self.name},{self.gender},{self.phone})'.format(self=self)

print(str(Customer('Lisa','Female','67889')))
# Customer(Lisa,Female,67889)/<code>


4)格式化元组的具体项。

<code>point=(1,3)
print('X:{0[0]};Y:{0[1]}'.format(point))
# X:1;Y:3/<code>


第三部分:结论

在了解了两种字符串格式的基本用法后,我们发现还是要尽量使用format方式而不是%操作符来格式化字符串。

理由一:format方式在使用上较%操作符更为灵活。使用format方式时,参数的顺序与格式化的顺序不必完全相同。如:

<code>print('The number {1} in hex is:{1:#x}, the number {0} in oct is {0:#o}'.format(4746,45))
# The number 45 in hex is:0x2d, the number 4746 in oct is 0o11212/<code>

上例中格式化的顺序为{1},{0},其对应的参数申明的顺序却相反,{1}与45对应,而用%方法需要使用字典形式才能达到同样的目的。


理由二:format方式可以方便地作为参数传递。

<code>weather = [('Monday','rain'),('Tuesday','sunny'),('Wednesday','sunny'),('Thursday','rain'),('Friday','cloudy')]
formatter = "Weather of '{0[0]}' is '{0[1]}'".format
for item in map(formatter, weather):
    print(item)
#Weather of 'Monday' is 'rain'
Weather of 'Tuesday' is 'sunny'
Weather of 'Wednesday' is 'sunny'
Weather of 'Thursday' is 'rain'
Weather of 'Friday' is 'cloudy'/<code>


理由三:%最终会被.format方式所代替。这个理由可以认为是最直接的原因,在Python3.0中.format方法是推荐使用的方法,而之所以仍然保留%操作符是为了保持向后兼容。


理由四:%方法在某些特殊情况下使用时需要特别小心。

<code>item_name = ('mouse', 'mobilephone','cup')
print('item_list are %s'%(item_name))  # 使用%方法格式化元组
# TypeError: not all arguments converted during string formatting

print('item_list are %s'%(item_name,))  # 注意后面的逗号
# item_list are ('mouse', 'mobilephone', 'cup')

print('item_list are {}'.format(item_name))  # 使用format方法直接格式化不会抛出异常
# item_list are ('mouse', 'mobilephone', 'cup')/<code>

该例子本意是把item_name看做一个整体来进行格式化,但直接使用时却抛出TypeError,对于%直接格式化字符的这种形式,如果字符本身为元组,则需要使用在%使用(item_name,)这种形式才能避免错误,注意逗号。

关注微信公众号“Python小镇”,发现更多干货知识!


分享到:


相關文章: