目录
3.3 字符串格式化:完整版
格式化字符串的右操作数可以是任意类型,如果是元组或者映射类型(如字典),那么字符串格式化将会有所不同。我们尚未涉及映射(如字典),在此先了解一下元组。第4张还会详细介绍映射的格式化。
如果右操作数是元组的话,则其中的每一个元素都会被单独格式化,每个值都需要一个对应的转换说明符。
Ps:如果需要转换的元组作为转换表达式的一部分存在,那么必须将它用圆括号括起来,避免出错。
>>> '%s plus %s equals %s' % (1, 1, 2)
'1 plus 1 equals 2'
>>> '%s plus %s equals %s' % 1, 1, 2 #Lacks parentheses!
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> '%s plus' % 1, 1, 2 #Lacks parentheses! #只识别了第一个1,其余1 2是并列关系
('1 plus', 1, 2)
基本的转换说明符(与此相对应的是完整的转换说明符,也就是包括映射键的说明符,第四章)包括以下部分。注意,这些项的顺序是至关重要的。
(1)%字符:标记转换说明符的开始。
(2)转换标志(可选):- 表示左对齐; + 表示在转换值之前要加上正负号; “ ”(空白字符)表示正数之前保留空格; 0 表示转换值若位数不够则用0填充。(见后3.3.3)
(3)最小字段宽度(可选):转换后的字符串至少应该具有该值指定的宽度,如果是*,则宽度会从值元组中读出。(见后3.3.2)
(4)点(.)后跟精度值(可选):如果转换的是实数,精度值就表示出现在小数点后的位数,如果转换的是字符串,那么该数字就表示最大字段宽度。如果是*,那么精度将会从元组中读出。(见后3.3.2)
(5)转换类型:见表3-1
转换类型 | 含义 |
d,i | 带符号的十进制整数 |
o | 不带符号的八进制 |
u | 不带符号的十进制 |
x | 不带符号的十六进制(小写) |
X | 不带符号的十六进制(大写) |
e | 科学计数法表示的浮点数(小写) |
E | 科学计数法表示的浮点数(大写) |
f.F | 十进制浮点数 |
g | 如果指数大于-4或者小于精度值则和e相同,其它情况与f相同 |
G | 如果指数大于-4或者小于精度值则和E相同,其它情况与F相同 |
c | 单字符(接受整数或者单字符字符串) |
r | 字符串(使用repr转换任意python对象)(repr:创建一个字符串,以合法的python表达式来表示值,repr是函数,而str是一种类型) |
s | 字符串(使用str转换任意python对象) |
3.3.1 简单转换
简单的转换只需要写出转换类型:
>>> 'Price of eggs: $%d' % 42 #%d 带符号的十进制
'Price of eggs: $42'
>>> 'Hexadecimal of eggs: %x' % 42 #不带符号的十六进制
'Hexadecimal of eggs: 2a'
>>> from math import pi #引入math pi模块
>>> 'Pi: %f...' % pi #十进制浮点数
'Pi: 3.141593...'
>>> 'Very inexact estimate of pi: %i' % pi #十进制数i,d
'Very inexact estimate of pi: 3'
>>> 'Using str: %s' %42L #字符串
'Using str: 42'
>>> 'Using str: %r' %42L #字符串repr函数
'Using str: 42L'
3.3.2 字段宽度和精度
转换说明符可以包括字段宽度和精度。字段宽度是转换后的值所保留的最小字符个数,精度(对于数字转换来说)则是结果中应该包含的小数位数,或者(对于字符串转换来说)是转换后的值所能包含的最大字符个数。
这两个参数都是整数(首先是字段宽度,然后是精度),通过点号(.)分隔。虽然两个都是可选的参数,但如果只给出精度,就必须包含点号:
>>> '%10f' % pi #字段宽 10
' 3.141593'
>>> '%10.2f' % pi #字段宽 10,精度 2
' 3.14'
>>> '%.2f' % pi #精度 2
'3.14'
>>> '%.5s' % 'Guido van Rossum'
'Guido'
可以使用*(星号)作为字段宽度或者精度(或者两者都使用*),此时数值会从元组参数中读出:
>>> '%.*s' % (5,'Guido van Rossum')
'Guido'
>>> '%10.*s' % (5,'Guido van Rossum') #总字段宽度为10,打印的字符串5个
' Guido'
>>> '%10.*s' % (12,'Guido van Rossum')
'Guido van Ro' #12个字符,设置了10个字段宽度(最小字符个数),精度为12(最大字符个数)
3.3.3 符号、对齐和用0填充
在字段宽度和精度值之前还可以放置一个“标志”,该标志可以是零、加号、减号或空格。零表示数字将会用0填充。
>>> '%010.2f' % pi #0 表示转换值若位数不够则用0填充。
'0000003.14'
注意,在010中开头的那个0并不意味着字段宽度说明符为八进制数,他只是个普通的python数值。当使用010作为字段宽度说明符的时候,表示字段宽度为10,并且用0进行填充空位,而不是说字段宽度为8:
>>> 010
8
减号(-)用来左对齐数值
>>> '%-10.2f' % pi #前面有提到-:-左对齐
'3.14 ' #在数字右侧多出了额外的空格
而空白“ ”意味着正数前加上空格;这在需要对齐正负数时会很有用:
>>> print ('% 5d' %10) + '\n' + ('% 5d' % -10)
10
-10
最后加号(+)不管正数还是负数都标示出正负号(同样对齐时很有用)
>>> print ('%+5d' %10) + '\n' + ('%+5d' % -10)
+10
-10
代码清单3-1 字符串格式化示例
[root@mds1 python]# vim stringFormat.py
#!/usr/bin/python2
#coding=utf-8
#使用给定的宽度打印格式化后的价格列表
width = input('Please enter width: ')
price_width = 10
item_width = width - price_width
header_format = '%-*s%*s'
format = '%-*s%*.2f'
print '=' * width
print header_format % (item_width, 'Item', price_width, 'Price')
print '-' * width
print format % (item_width, 'Apples', price_width, 0.4) #'%-*s%*.2f' % (25,'Apples',10,0.4)
print format % (item_width, 'Pears', price_width, 0.5)
print format % (item_width, 'Cantaloupes', price_width, 1.92)
print format % (item_width, 'Dried Apricots (16 oz.)', price_width, 8)
print format % (item_width, 'Prunes (4 lbs.)', price_width, 12)
print '=' * width
[root@mds1 python]# chmod a+x stringFormat.py
[root@mds1 python]# ./stringFormat.py
Please enter width: 35
===================================
Item Price
-----------------------------------
Apples 0.40
Pears 0.50
Cantaloupes 1.92
Dried Apricots (16 oz.) 8.00
Prunes (4 lbs.) 12.00
===================================