在学习Python的过程中,我们常常会使用print语句,用于字符串输出。一般情况下,我们是这么使用的:
>>> print('hello world')
hello world
>>> print('hello%s' %('world'))
hello world
今天我们介绍一下用format格式化输出字符串。
format的一个例子
print('hello {0}'.format('world'))
#会输出hello world
使用format格式化输出字符串具有不需要理会数据类型的问题(在%方法中%s只能替代字符串类型),单个参数可以多次输出,参数顺序可以不相同等等优势。
str.format()方法包含由花括号{}包围的“替换字段”。任何不包含在大括号中的内容都将被视为文字文本,并将其原样复制到输出中。如果您需要在字面文本中包含大括号字符,则可以通过加倍{{和}}来将其转义。
format的语法格式
替换字段的语法如下所示:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
arg_name ::= [identifier | integer]
attribute_name ::= identifier
element_index ::= integer | index_string
index_string ::= +
conversion ::= "r" | "s" | "a"
format_spec ::=
field_name本身以一个数字或关键字的arg_name开头。 如果它是一个数字,它指的是一个位置参数,如果它是一个关键字,则它指的是一个已命名的关键字参数。 如果格式字符串中的数字arg_names依次为0,1,2,...,则它们可以全部省略(不仅仅是一些),并且数字0,1,2,...将按照该顺序自动插入(Python3.1以上版本)。
例如:
>>> print('he{} {}'.format('llo','world'))
hello world
>>> print('he{0} {1}'.format('llo','world'))
hello world
又如:
"First, thou shalt count to {0}" # 引用第一个位置参数
"Bring me a {}" # 隐式引用第一个位置参数
"From {} to {}" # 同"从{0}到{1}"
"My quest is {name}" # 引用关键字参数'name'
"Weight in tons {0.weight}" # 第一个位置参数的'weight'属性
"Units destroyed: {players[0]}" # 关键字参数'players'的第一个元素
格式化之前,转换字段会导致类型强制转换。 通常,格式化值的工作是通过值本身的__format __()方法完成的。 但是,在某些情况下,希望强制将某个类型格式化为字符串,并覆盖自己的格式定义。 通过在调用__format __()之前将该值转换为字符串,将绕过正常的格式化逻辑。
目前支持三种转换标志:'!s'它调用str(),'!r'调用repr(),'!a'调用ascii()。例如:
"Harold's a clever {0!s}" # 在参数上调用str()
"Bring out the holy {name!r}" # 在参数上调用repr()
"More {!a}" # 在参数上调用ascii()
语法格式看不懂?没关系,下面会有具体的例子,看例子就懂得用了。
format实际应用举例
str.format()语法的示例以及与旧%格式的比较:在大多数情况下,语法与旧的%格式类似,但添加了{}和:而不是%。 例如,'%03.2f'可以翻译为'{:03.2f}'。
新的格式语法也支持新的和不同的选项,如下面的例子所示:
1. 通过位置来填充字符串
print('{0}, {1}, {2}'.format('a', 'b', 'c')) #a, b, c
print('{}, {}, {}'.format('a', 'b', 'c')) # a, b, c
print('{2}, {1}, {0}'.format('a', 'b', 'c'))# c, b, a
print('{2}, {1}, {0}'.format(*'abc')) # c, b, a
print('{0}{1}{0}'.format('abra', 'cad')) # abracadabra
foramt会把参数按位置顺序来填充到字符串中,第一个参数是0,然后1……
也可以不输入数字,这样也会按顺序来填充
同一个参数可以填充多次,这个是format比%先进的地方
2. 按名称访问参数
print('Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W'))
#Coordinates: 37.24N, -115.81W
coord = {'latitude': '37.24N', 'longitude': '-115.81W'}
print('Coordinates: {latitude}, {longitude}'.format(**coord))
#Coordinates: 37.24N, -115.81W
3. 通过参数的属性访问
c = 3-5j
print(('The complex number {0} is formed from the real part {0.real} and the imaginary part {0.imag}.').format(c))
#The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __str__(self):
return 'Point({self.x}, {self.y})'.format(self = self)
print(str(Point(4, 2)))
#Point(4, 2)
4. 通过参数的items访问
coord = (3, 5)
print('X: {0[0]}; Y: {0[1]}'.format(coord))
#X: 3; Y: 5
5. 替换%s和%r
print("repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2'))
#"repr() shows quotes: 'test1'; str() doesn't: test2"
6. 对齐文本并指定宽度
print('{:<30}'.format('left aligned'))
#'left aligned '
print('{:>30}'.format('right aligned'))
#' right aligned'
print('{:^30}'.format('centered'))
#' centered '
print('{:*^30}'.format('centered'))
# use '*' as a fill char
#'***********centered***********'
还能这样:
7. 替换%+f,%-f和%f并指定一个符号
print('{:+f}; {:+f}'.format(3.14, -3.14))
# show it always#'+3.140000; -3.140000'
print('{: f}; {: f}'.format(3.14, -3.14))
# show a space for positive numbers#' 3.140000; -3.140000'
print('{:-f}; {:-f}'.format(3.14, -3.14)
# show only the minus -- same as '{:f}; {:f}'
#'3.140000; -3.140000'
8. 替换%x和%o并将该值转换为不同的基值
# 格式也支持二进制数字
print("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42))
#'int: 42; hex: 2a; oct: 52; bin: 101010'
# 以0x,0o或0b作为前缀
print("int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42))
#'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'
b、d、o、x分别是二进制、十进制、八进制、十六进制
9. 使用逗号作为千位分隔符
print('{:,}'.format(1234567890))
#'1,234,567,890'
10. 表示一个百分比
points = 19
total = 22
print('Correct answers: {:.2%}'.format(points/total))
#Correct answers: 86.36%
11. 使用特定于类型的格式
import datetime
d = datetime.datetime(2010, 7, 4, 12, 15, 58)
print('{:%Y-%m-%d%H:%M:%S}'.format(d))
#'2010-07-04 12:15:58'
12. 更复杂的例子:
for align, text in zip('<^>', ['left', 'center', 'right']):
print('{0:{fill}{align}16}'.format(text, fill=align, align=align))
#left<<<<<<<<<<<<
#^^^^^center^^^^^
#>>>>>>>>>>>right
octets = [192, 168, 0, 1]
print('{:02X}{:02X}{:02X}{:02X}'.format(*octets))
#'C0A80001'
width = 5
for num in range(5,12):
for base in 'dXob':
print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ')
print()
# 5 5 5 101
# 6 6 6 110
# 7 7 7 111
# 8 8 10 1000
# 9 9 11 1001
# 10 A 12 1010
# 11 B 13 1011
最后
在实操中遇到问题?欢迎来讨论。