>>> from env_helper import info; info()
页面更新时间: 2023-12-27 09:26:08
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-16-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

3.10. 格式化字符串时尽量使用 .format 方式而不是 %

Python中内置的 % 操作符和 .format 方式都可用于格式化字符串。 先来看看这两种具体格式化方法的基本语法形式和常见用法。

%操作符根据转换说明符所规定的格式返冋一串格式化后的字符串,转换说明符的基本形式为:% [转换标记][宽度[.精确度]]转换类型。 其中常见的转换标记和转换类型分别如下图所示如果未指定宽度,则默认输出为字符串本身的宽度。

_images/28-1.png _images/28-2.png

%操作符格式化字符串时有如下儿种常见用法:

直接格式化字符或者数值

>>> print ("your score is %06.1f"% 9.5)
your score is 0009.5

以元组的形式格式化

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

以字典的形式格式化

itemdict = { 'itemname': 'circumference',

'radius':3, 'value':math.pi*radius*2 }

print("the %(itemname)s of a circle with radius %(radius)s is %(value)0,3f " %itemdict)

.format方式格式化字符串的基本语法为:[[填充符】对齐方式][符号宽度]U [.精确度][转换类型]。其中填充符可以是除了”{”和“}”符号之外的任意符号,对齐 方式和符号分别如下表所示。转换类型跟%操作符的转换类型类似 image1 image2

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

使用位置符号a

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

使用名称

>>> print ("the max number is {max} r the min number is {min}, the average number {average:0.3f}".format(max=189,min=12.6, average=23.5))
the max number is 189 r the min number is 12.6, the average number 23.500

通过属性

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

格式化元组的具体项

>>> point = (1,3)
>>> print( "X:{0[0]};Y:{0[1]}".format(point))
X:1;Y:3

在了解了两种字符串格式的基本用法之后我们再回到本节开头提出的问题:为什么要尽 量使用format方式而不是%操作符来格式化字符串。

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

>>> 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

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

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

>>> weather=[ ("Monday"," rtrainw") ,("MTuesday#", "sunny"),("HWednesday","wsunnyrt"), ("MThurs day","rain"),("Friday","cloud")]
>>> formatter= "Weather of {0[0]} is  {0[1]}  ". format
>>> for item in map(formatter, weather):#format 方法作为第一个参数传速给 map 函数
>>>     print(item)
Weather of Monday is   rtrainw
Weather of MTuesday# is  sunny
Weather of HWednesday is  wsunnyrt
Weather of MThurs day is  rain
Weather of Friday is  cloud

理由三: % 最终会被 .format() 方式所代替

这个理由可以认为是最直接的原因,根据 Python 的官方文档(http://docs.python_org/2/library/stdtypw.htra]#string-formatting), .format() 方法最终会取代 % ,在Python3.0中 .format() 方法是推荐使用的方法,而之所以仍然保留 % 操作符是为了保持向后兼容。

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

>>> itemname = ("rmouse"," mobilephon"," cup")
>>> print ("itemlist are %s"%(itemname))
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[9], line 2
      1 itemname = ("rmouse"," mobilephon"," cup")
----> 2 print ("itemlist are %s"%(itemname))


TypeError: not all arguments converted during string formatting
>>> print ("witeinlist are %s" % (itemname,))
witeinlist are ('rmouse', ' mobilephon', ' cup')
>>> print ("rtitemlist are {}11". format (itemname)) # 使用 format 方法直接格式化不会抛出异常
rtitemlist are ('rmouse', ' mobilephon', ' cup')11

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