字符串格式化

字符串格式化对于每个语言来水都是一个非常基础和使用的功能,学习Python的同学大概都知道可以用 % 语法来格式化字符串。然而为了让我们更方便的使用这个功能,语言本身也在对字符串格式化的方法进行迭代!

% 操作符 [ Python2.6 - ]

在 Python2.6之前,字符串迭代只有一种方法,就是 % 操作符,效果和 C语言中的 % 类似

print("my name is %s , age is %d" % ("Tom", 18))
# my name is Tom , age is 18

% 符号前边使用一个字符串作为模板,模板中有标记格式的占位符号,详见下方表格:

占位符 描述
%d 十进制整数
%o 八进制整数
%x 十六进制(小写)
%X 十六进制(大写)
%f 浮点数
%s 字符串

除了对数据类型的指定, % 操作符还支持更复杂的格式控制

%[数据名称][对齐标志][宽度].[精度]类型

format函数 [ Python2.6 + ]

到 Python2.6时,出现了一种新的字符串格式化方法,str.format()函数,format函数 使用 {}: 代替了 % ,威力更为强大!

# 不指定参数位置 'hello world'
'{} {}'.format("hello","world")

# 指定参数位置 'hello world'
'{0} {1}'.format("hello","world")

# 参数可以使用多次 'world:hello world'
'{1}:{0} {1}'.format("hello","world")

# 使用关键字参数 'tom27'
'{name}{age}'.format(name='tom', age=27)

# 通过下标映射 'hello world'
'{0[0]} {0[1]}'.format(["hello", "world"])

# 通过key映射 'tom 18'
'{0[name]} {0[age]}'.format({
   "name":"tom", "age":18})

# 按对象属性映射 'tom 27'
'{person.name} {person.age}'.format(person=person)

# 字典解包 'tom 18'
'{name} {age}'.format(**{
   "name":"tom", "age":18})

# 列表解包 'hello world'
'{0} {1}'.format(*["hello", "world"])

在复杂格式控制方面,format函数也提供了更加强大的控制方式:

[填充字符]对齐方式][符号标志][#][宽度][,][.精度][类型]

=========================
'{:S^+#016,.2f}'.format(1234)
# 'SSS+1,234.00SSSS'
类型 描述
填充字符 按照输入填充,不填时默认空格填充
对齐方式 ^居中,<左对齐,>右对齐
符号标志 +表示有符号(整数前显示+,负数前显示-),空格表示整数前加一个空格以和负数对齐
# 是否在二进制,八进制,十六进制前显示0b0o0x等符号
宽度 输出字符串的宽度
, 使用千位分隔符
精度 小数点后数字位数 .2精度为2位
类型 s 字符串,c 字符,bod分别表示二八十进制,xX表示小写和大写十六进制,eE表示小写和大写的科学记数法,f 浮点型

可以看到 format函数 在 % 基础上丰富了格式控制种类,并且使输出更容易!

f-string [ python3.6 +]

不少使用过 ES6的小伙伴会知道其中的模板字符串,采用直接在字符串中内嵌变量的方式进行字符串格式化操作,Python3.6 版本中也为我们带来了类似的功能:Formatted String Literals(字面量格式化字符串),简称f-string

name = "tom"
age = 18
print(f"{name} & {age}")
# tom & 18

同时,f-string 的性能是比 %format 都有提升的,我们做一个简单的测试,分别使用三种格式化语句执行10000次:

print('My name is %s and i'm %s years old.' % (name, age))
print('My name is {} and i'm {
   } years old.'.format(name, age))
print(f'My name is {name} and i'm {
   age} years old.')