str对象的format函数

2020年5月15日 / 35次阅读 / Last Modified 2020年8月28日
字符串

python老式的%-style字符串格式化方式,在易用性方面还是要欠一点。从python 2.6开始有了format方式,这种方式出现的也比较早,兼容性应该也是可以的。

format方式,是使用{}来对应要替换的内容:

>>> '{}-{}-{}'.format(1,2,3)
'1-2-3'
>>> '{}-{}-{}'.format('a','b','c')
'a-b-c'

在{}中,可以用数字来定位,因此也可以对相同的内容进行多次替换:

>>> '{0}-{1}-{0}'.format(1,2)
'1-2-1'
>>> '{1}-{0}-{1}'.format(1,2)
'2-1-2'
>>> '{1}-{0}-{1}'.format(1,2,3)
'2-1-2'
>>> '{9}-{0}-{1}'.format(1,2,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

注意IndexError异常,format函数的参数只有3个,而格式化字符串里有index 9。如果{}中不指定index,默认是递增的。

不用在{}中指定要替换对象的类型(%-style用%s表示字符串,%d表示整数,%f表示浮点数):

>>> '{} {}'.format(1,2)
'1 2'
>>> '{} {}'.format('a','b')
'a b'
>>> '{} {}'.format(1.23,4.56)
'1.23 4.56'

list和tuple对象可以直接被当成format函数的参数来用:

>>> a
[1, 2, 3]
>>> b
('a', 'b', 'c')
>>> '{} {} {}'.format(*a)
'1 2 3'
>>> '{} {} {}'.format(*b)
'a b c'
>>> '{}'.format(a)
'[1, 2, 3]'
>>> '{0}--{0}--{0}'.format(a)
'[1, 2, 3]--[1, 2, 3]--[1, 2, 3]'

注意,如果不使用*操作符(unpacking),可以生产字符串,format函数的原理,(似乎是)通过参数对象的__str__函数(用str调用)来获取字符串。

再看一个示例:

>>> '{0} {0} {0}'.format(*a)
'1 1 1'
>>> '{0[0]} {0[1]} {0[2]}'.format(a)
'1 2 3'
>>> '{0[0]} {1[1]} {1[2]}'.format(a,b)
'1 b c'

不使用unpacking操作也可以,直接在{}中引用第几个元素的某个index!再想想format函数的内部逻辑:按index取对象,对象也可以有自己index,然后对对象执行str函数,将获取的string拼接起来。

格式化字符串的{}中,可以空,可以index(不能部分空,部分index),也可以是key值:

>>> d
{'a': 1, 'b': 3, 'c': 3}
>>> '{a},{b},{c}'.format(**d)
'1,3,3'
>>> '{a},{b},{c}'.format(a=1,b=2,c=3)
'1,2,3'

也就是说,{}中的index不一定是数字,key也可以。

有了上面的感性认识后,我发现在{}中可以直接调用format函数参数对象的attribute,function不行:

>>> b
('a', 'b', 'c')
>>> '{0[1].__doc__}'.format(b)
"str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'."
>>> '{0[1].upper()}'.format(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'upper()'

{0[1].__doc__}表示第0个对象的index为1的元素的__doc__属性。

上面主要是总结format格式化的index引用。下面总结format格式化的格式化特性。

用format来对齐字符串:

>>> '{:->8}'.format(0)
'-------0'
>>> '{:-<8}'.format(0)
'0-------'
>>> '{:-^8}'.format(0)
'---0----'

{:->8}::前没有数字,默认就是0,:后面是格式化方式,-为填充符,>表示右对齐,8表示宽度。

<表示左对齐;^表示居中。

推荐阅读:关于含中文字符串的对齐问题

精度和符号:

>>> '{:f}'.format(1.2345)
'1.234500'
>>> '{:.2f}'.format(1.2345)
'1.23'
>>> '{:.3f}'.format(1.2345)
'1.234'
>>> '{:+.3f}'.format(1.2345)
'+1.234'
>>> '{:+.3f}'.format(-1.2345)
'-1.234'
>>> '{:+.0f}'.format(-1.2345)
'-1'
>>> '{:+.0f}'.format(2.71828182)
'+3'
>>> '{:.0f}'.format(2.71828182)
'3'
>>> '{:.2f}'.format(2.71828182)
'2.72'
>>> '{:.4f}'.format(2.71828182)
'2.7183'
>>> '{:.1f}'.format(2.45)
'2.5'
>>> '{:.1f}'.format(2.35)
'2.4'
>>> '{:.1f}'.format(2.25)
'2.2'
>>> '{:.1f}'.format(2.15)
'2.1'

这段测试代码有点长,要说明几个细节:

1, {:+.2f},表示带符号(一定有符号)显示小数点后两位;

2, 有舍入时,不是四舍五入!应该是与python内置的round函数一致的舍入方式。

精度和符号可以与对齐方式一起使用:

>>> '{:*>8.1f}'.format(2.15)
'*****2.1'
>>> '{:*<8.1f}'.format(2.15)
'2.1*****'
>>> '{:*^8.1f}'.format(2.15)
'**2.1***'
>>> '{:*^8+.1f}'.format(-2.15)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Invalid format specifier

但是单上符号就不行了。

用逗号分隔数字

>>> '{:,}'.format(12345678)
'12,345,678'
>>> '{:,}'.format(1.2345678)
'1.2345678'
>>> '{:,}'.format(1234567.8)
'1,234,567.8'
>>> '{:#>16,}'.format(1234567.8)
'#####1,234,567.8'
>>> '{:#<16,}'.format(1234567.8)
'1,234,567.8#####'

百分比格式:

>>> '{:%}'.format(0.24)
'24.000000%'
>>> '{:.2%}'.format(0.24)
'24.00%'
>>> '{:.2%}'.format(0.2415)
'24.15%'
>>> '{:.2%}'.format(0.241515)
'24.15%'
>>> '{:.2%}'.format(0.241555)
'24.16%'
>>> '{:+.2%}'.format(0.241555)
'+24.16%'
>>> '{:+.2%}'.format(-0.241555)
'-24.16%'
>>> '{:+>16.2%}'.format(-0.241555)
'+++++++++-24.16%'
>>> '{:+<16.2%}'.format(-0.241555)
'-24.16%+++++++++'

科学计数:

>>> '{:e}'.format(100000000000)
'1.000000e+11'
>>> '{:.2e}'.format(100000000000)
'1.00e+11'
>>> '{:+.2e}'.format(100000000000)
'+1.00e+11'
>>> '{:$>16.2e}'.format(100000000000)
'$$$$$$$$1.00e+11'

不同的进制:

>>> '{:b}'.format(12345)
'11000000111001'
>>> '{:o}'.format(12345)
'30071'
>>> '{:x}'.format(12345)
'3039'
>>> '{:d}'.format(12345)
'12345'

-- EOF --

本文链接:https://www.pynote.net/archives/1922

留言区

电子邮件地址不会被公开。 必填项已用*标注


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top