目录
一 %号
二 str.format
2.1 常使用方式
2.2 填充与格式化
2.3 精度与进制
三 f-String
%号格式化字符串的方式从Python诞生之初就已经存在,时至今日,python官方也并未弃用%号,但也并不推荐这种格式化方式。
该方式支持:单个元素、多个元素(元组)、字典、关键字参数
【举例1】格式的字符串(即%s)与被格式化的字符串(即传入的值)必须按照位置一一对应
# ps:当需格式化的字符串过多时,位置极容易搞混
print('%s asked %s to do something' % 'lsj') # lsj only, 单个元素
print('%s asked %s to do something' % ('lsj', 'lili')) # 多个元素,使用元组
【举例2】可以通过字典方式格式化,打破了位置带来的限制与困扰
print('我的名字是 %(name)s, 我的年龄是 %(age)s.' % {'name': 'lsj', 'age': 18})
【举例3】使用kwargs: 关键字参数方式,直接引用
kwargs={'name': 'lsj', 'age': 18}
print('我的名字是 %(name)s, 我的年龄是 %(age)s.' % kwargs)
该format
方法是在Python 2.6中引入的,是字符串类型的内置方法。因为str.format的方式在性能和使用的灵活性上都比%号更胜一筹,所以推荐使用。
2.1.1 位置参数方式
# 按照位置一一对应 print('{} asked {} to do something'.format('lsj', 'lili')) # lsj asked lili to do something print('{} asked {} to do something'.format('lili', 'lsj')) # lili asked lsj to do something
2.1.2 索引方式
# 使用索引取对应位置的值 print('{0}{0}{1}{0}'.format('x','y')) # xxyx
2.1.3 关键字参数或字典
# 可以通过关键字or字典方式的方式格式化,打破了位置带来的限制与困扰 2.1.3.1 字典方式 print('我的名字是 {name}, 我的年龄是 {age}.'.format(age=18, name='lsj')) 2.1.3.2 关键字方式 **kwargs kwargs = {'name': 'lsj', 'age': 18} print('我的名字是 {name}, 我的年龄是 {age}.'.format(**kwargs)) # 使用**进行解包操作
# 先取到值,然后在冒号后设定填充格式:[填充字符][对齐方式][宽度] # *<10:左对齐,总共10个字符,不够的用*号填充 print('{0:*<10}'.format('开始执行')) # 开始执行****** # *>10:右对齐,总共10个字符,不够的用*号填充 print('{0:*>10}'.format('开始执行')) # ******开始执行 # *^10:居中显示,总共10个字符,不够的用*号填充 print('{0:*^10}'.format('开始执行')) # ***开始执行***
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
str.format() 比 %格式化高级了一些,但是它还是有自己的缺陷。当需要传入的字符串过多时,仍然会显得非常冗长。与在Python 3.6中引入 了f-strings,不仅比str.format更简洁,性能上也更胜一筹,定义:
f
-
string是以f或F开头的字符串, 核心在于字符串中符号{}的使用
3.1 {}中可以是变量名
name = 'lsj' age = 18 print(f'{name} {age}') # lsj 18 print(F'{age} {name}') # 18 lsj
3.2 {}中可以是表达式
# 可以在{}中放置任意合法的Python表达式,会在运行时计算 # 比如:数学表达式 print(f'{3*3/2}') # 4.5 # 比如:函数的调用 def foo(n): print('foo say hello') return n print(f'{foo(10)}') # 会调用foo(10),然后打印其返回值 # 比如:调用对象的方法 name='lsj' print(f'{name.lower()}') # lsj
3.3 在类中的使用
>>> 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('lsj',18) >>> print(obj) # 触发__str__ lsj:18 >>> obj # 触发__repr__ ===>lsj:18<=== >>> >>> >>> >>> # 在f-Strings中的使用 >>> f'{obj}' # 触发__str__ 'lsj:18' >>> f'{obj!r}' # 触发__repr__ '===>lsj:18<==='
3.4 多行f-Stings
# 当格式化字符串过长时,如下列表info name = 'lsj' 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) # ['名字:lsj年龄:18性别:male', '第一个爱好:play第二个爱好:music第三个爱好:read']
3.5 引号的嵌套
# 当字符串嵌套发送冲突时,与正常的字符串处理方式是一样的 # 1、外层为单引号,内层嵌套也为单引号,并且想要输入的内容也为单引号,那么外层需要改用双引号 print("my name is 'lsj'") # 2、外层为单引号,内层嵌套也为单引号,并且想要输入的内容也为单引号,需要用到转义 print('my name is \'lsj\'')
3.6 注意
#1、反斜杠可以用来进行字符转义,但不能用在{}的表达式中 f'{1\2}' # 语法错误 #2、注释#号也不能出现在{}的表达式中 f'{x#}' # 语法错误
3.7 括号的处理
基于3.5我们得知,不能在{}内出现反斜杠\,所以,当我们的输出的结果中需要包含{}时,下面的做法就是错误的
print(f'\{天王盖地虎\}')
类似于输出%号的做法
>>> print('%s%%' %30) 30%
若想输出{},那么需要在原有的基础上再套一层,如下
print(f'{{天王盖地虎}}') # {天王盖地虎} print(f'{{{{天王盖地虎}}}}') # {{天王盖地虎}}
性能对比=>f_Stings性能最高
from timeit import timeit def test_s(): name = 'lsj' age = 18 return '%s:%s.' % (name, age) def test_format(): name = 'lsj' age = 18 return '{}:{}.'.format(name, age) def test_f_strings(): name = 'lsj' age = 18 return f'{name}:{age}.' res1 = timeit(test_s, number=1000000) res2 = timeit(test_format, number=1000000) res3 = timeit(test_f_strings, number=1000000) print(res1) # 0.3709844550030539 print(res2) # 0.47834375899401493 print(res3) # 0.3111891380031011, 最快