# 方式一、%符号 %号格式化字符串的方式从Python诞生之初就已经存在,时至今日,python官方也并未弃用%号。 ```python # 格式的字符串(即%s)与被格式化的字符串(即传入的值)必须按照位置一一对应 print('%s asked %s to do something' % ('egon', 'lili')) # egon asked lili to do something print('%s asked %s to do something' % ('lili', 'egon')) # lili asked egon to do something # 可以通过字典方式格式化,打破了位置带来的限制与困扰 print('我的名字是 %(name)s, 我的年龄是 %(age)s.' % {'name': 'egon', 'age': 18}) kwargs={'name': 'egon', 'age': 18} print('我的名字是 %(name)s, 我的年龄是 %(age)s.' % kwargs) ``` | 转换符 | 说明 | | ------ | --------------------------------------------- | | %d, %i | 转换为带符号的十进制整数 | | %o | 转换为带符号的八进制整数 | | %x, %X | 转换为带符号的十六进制整数 | | %e, %E | 转化为科学计数法表示的浮点数(e 小写或E大写) | | %f, %F | 转化为十进制浮点数 | | %g, %G | 智能选择使用 %f 或 %e 格式(%F 或 %E 格式) | | %c | 格式化字符及其 ASCII 码 | | %r | 使用 repr() 函数将表达式转换为字符串 | | %s | 使用 str() 函数将表达式转换为字符串 | ## 指定最小输出宽度 ```python n = 1234567 print("n(10):%10d." % n) print("n(5):%5d." % n) url = "http://c.biancheng.net/python/" print("url(35):%35s." % url) print("url(20):%20s." % url) ``` ## 指定对齐方式 默认情况下,print() 输出的数据总是右对齐的。也就是说,当数据不够宽时,数据总是靠右边输出,而在左边补充空格以达到指定的宽度。Python 允许在最小宽度之前增加一个标志来改变对齐方式,`-` 指定左对齐;`+` 指定右对齐; `0` 表示宽度不足时补零。对于整数,指定左对齐时,在右边补 0 是没有效果的,因为这样会改变整数的值。对于小数,以上三个标志可以同时存在。对于字符串,只能使用`-`标志,因为符号对于字符串没有意义,而补 0 会改变字符串的值。 ```python n = 123456 # %09d 表示最小宽度为9,左边补0 print("n(09):%09d" % n) # %+9d 表示最小宽度为9,带上符号 print("n(+9):%+9d" % n) f = 140.5 # %-+010f 表示最小宽度为10,左对齐,带上符号 print("f(-+0):%-+010f" % f) s = "Hello" # %-10s 表示最小宽度为10,左对齐 print("s(-10):%-10s." % s) #n(09):000123456 #n(+9): +123456 #f(-+0):+140.500000 #s(-10):Hello ``` ## 指定精度 ```python #使用方法 %m.nf %.nf f = 3.141592653 # 最小宽度为8,小数点后保留3位 print("%8.3f" % f) # 最小宽度为8,小数点后保留3位,左边补0 print("%08.3f" % f) # 最小宽度为8,小数点后保留3位,左边补0,带符号 print("%+08.3f" % f) ``` # 方式二、str.format ## 内置格式码 ```python 整数: 'bcdoxXn' 浮点数: 'eEfFgGn%' 字符串: 's' ``` ## 使用位置参数 ```python # 按照位置一一对应 print('{} asked {} to do something'.format('egon', 'lili')) # egon asked lili to do something print('{} asked {} to do something'.format('lili', 'egon')) # lili asked egon to do something ``` ## 使用索引 ```python # 使用索引取对应位置的值 print('{0}{0}{1}{0}'.format('x','y')) # xxyx ``` ## 使用关键字参数或字典 ```python # 可以通过关键字or字典方式的方式格式化,打破了位置带来的限制与困扰 print('我的名字是 {name}, 我的年龄是 {age}.'.format(age=18, name='egon')) kwargs = {'name': 'egon', 'age': 18} print('我的名字是 {name}, 我的年龄是 {age}.'.format(**kwargs)) # 使用**进行解包操作 ``` ## 填充格式化 ```python # 先取到值,然后在冒号后设定填充格式:[填充字符][对齐方式][宽度] # *<10:左对齐,总共10个字符,不够的用*号填充 print('{0:*<10}'.format('开始执行')) # 开始执行****** # *>10:右对齐,总共10个字符,不够的用*号填充 print('{0:*>10}'.format('开始执行')) # ******开始执行 # *^10:居中显示,总共10个字符,不够的用*号填充 print('{0:*^10}'.format('开始执行')) # ***开始执行*** ``` ## 精度与进制格式化 ```python print('{salary:.3f}'.format(salary=1232132.12351)) #精确到小数点后3位,四舍五入,结果为:1232132.124 print('{0:b}'.format(123)) # 转成二进制,结果为:1111011 print('{0:o}'.format(9)) # 转成八进制,结果为:11 print('{0:x}'.format(15)) # 转成十六进制,结果为:f print('{0:,}'.format(99812939393931)) # 千分位格式化,结果为:99,812,939,393,931 ``` ## {!r}和{!s} ```python "value = {0!r}".format(a) # 等同于 "value = {0}".format(repr(a)) "name: {name!s}".format(name) # 等同于 "name: {name}".format(str(name)) ``` # 方式三、f-Strings str.format() 比 %格式化高级了一些,但是它还是有自己的缺陷。当需要传入的字符串过多时,仍然会显得非常冗长。自从python3.6版本依赖引入了f-Strings方法。 ## 变量填充 ```python name = 'egon' age = 18 print(f'{name} {age}') # egon 18 print(F'{age} {name}') # 18 egon ``` ## 表达式填充 ```python # 可以在{}中放置任意合法的Python表达式,会在运行时计算 # 比如:数学表达式 print(f'{3*3/2}') # 4.5 # 比如:函数的调用 def foo(n): print('foo say hello') return n print(f'{foo(10)}') # 会调用foo(10),然后打印其返回值 # 比如:调用对象的方法 name='EGON' print(f'{name.lower()}') # egon ``` ## 类中使用 ```python >>> class Person(object): ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def __str__(self): ... return f'{self.name}:{self.age}' ... def __repr__(self): ... return f'===>{self.name}:{self.age}<===' ... >>> >>> obj=Person('egon',18) >>> print(obj) # 触发__str__ egon:18 >>> obj # 触发__repr__ ===>egon:18<=== ``` ## 多行填充 ```python # 当格式化字符串过长时,如下列表info name = 'Egon' age = 18 gender = 'male' hobbie1='play' hobbie2='music' hobbie3='read' info = [f'名字:{name}年龄:{age}性别:{gender}',f'第一个爱好:{hobbie1}第二个爱好:{hobbie2}第三个爱好:{hobbie3}'] # 我们可以回车分隔到多行,注意每行前都有一个f info = [ # 第一个元素 f'名字:{name}' f'年龄:{age}' f'性别:{gender}', # 第二个元素 f'第一个爱好:{hobbie1}' f'第二个爱好:{hobbie2}' f'第三个爱好:{hobbie3}' ] print(info) # ['名字:Egon年龄:18性别:male', '第一个爱好:play第二个爱好:music第三个爱好:read'] ``` # 方式四、标准库模板 从Python 2.4起,Python标准库string引入了Template也可以用来格式化字符串,所以说,与前三种方式的一个显著区别就是:Template并属于python语言的核心语法特征。 ```python from string import Template name='EGON' t = Template('Hello $name!') res=t.substitute(name=name) print(res) # Hello EGON! #这个模板字符串不支持类似str.format那样的进制转换,需要我们自己处理 templ_string = 'Hello $name, there is a $error error!!!' res=Template(templ_string).substitute(name=name, error=hex(12345)) print(res) # Hello EGON, there is a 0x3039 error!!! ``` # 对比总结 1、如果格式化的字符串是由用户输入的,那么基于安全性考虑,推荐使用Template。 2、如果使用的python3.6+版本的解释器,推荐使用f-Stings。 3、如果要兼容python2.x版本的python解释器,推荐使用str.format。 4、如果不是测试的代码,不推荐使用%。