1 概念
- str.format()方法通过字符串中的大括号{}来识别替换字段replacement field,从而完成字符串的格式化。
- 替换字段由字段名field name和转换字段conversion field以及格式说明符 format specifier组成,即一般形式为 {字段名!转换字段:格式说明符}。
- 字段名分为简单字段名simple field name 和复合字段名 compound field name。而转换字段和格式说明符都是可选的。
2 字段名
简单字段名由三种写法:
- 省略字段名:{}
- 使用非负十进制整数{0}
- 变量名{name}
2.1 省略字段名
大括号内省略字段名,传递位置参数。
- 替换字段形式:{}
- 注意:大括号个数可以少于位置参数的个数,反之不行。
# 省略字段名传递位置参数
print('我叫{},今年{}岁。'.format('小陈',23))
#输出结果
#我叫小陈,今年23岁。# 大括号个数可以少于位置参数的个数
print('我喜欢吃{}和{}。'.format('凤梨','西瓜','榴莲'))
#输出结果
#我喜欢吃凤梨和西瓜。#大括号个数多于位置参数的个数则会报错
#print('今天吃{}和{}。'.format('鸡腿'))
#输出结果
#IndexError: tuple index out of range
2.2 数字字段名
可以通过数字形式的简单字段名传递位置参数。
- 数字必须是大于等于0的整数
- 带数字的替换字段可以重复使用
- 数字形式的简单字段名相当于把format中的所有位置参数整体当作一个元组,通过字段名中的数字进行取值。即{0}等价于tuple[0],所以大括号内的数字不能越界。
#通过数字形式的简单字段名传递位置参数
print('身高{0},住址{1}。'.format(1.80,'四合院'))
#输出结果
#身高1.8,住址四合院。#数字形式的简单字段名可以重复使用
print('我爱吃{0}。\n我不爱吃{1}。\n所以每天都买{0}。'.format('凤梨','柿子'))
#输出结果
#我爱吃凤梨。
#我不爱吃柿子。
#所以每天都买凤梨。#体会把所有位置参数整体当成元组来取值
print('我爱吃{1}、{3}和{0}。'.format('榴莲','炸鸡腿','扣肉','糖醋排骨'))
#输出结果
#我爱吃炸鸡腿、糖醋排骨和榴莲。#尝试一下越界错误
print('{1}'.format('错误用法'))
#输出结果
#IndexError: tuple index out of range
2.3 变量字段名
使用变量名形式的简单字段名传递关键字参数。
- 关键字参数的位置可以随意调换
#使用变量名形式的简单字段名传递关键字参数
print('我小弟是{name},今年{age}岁。'.format(name='阿花',age=16))
#输出结果
#我小弟是阿花,今年16岁。#关键字参数的顺序可以随意调换
print('我小弟是{name},今年{age}岁。'.format(age=16,name='阿花'))
#输出结果
#我小弟是阿花,今年16岁。
2.4 简单字段名的混合使用
- 混合使用数字形式和变量名形式的字段名,可以同时传递位置参数和关键字参数。
- 关键字参数必须位于位置参数之后
- 混合使用时可以省略数字
- 省略字段名{}不能和数字形式的字段名{非负整数}同时使用
#混合使用数字形式和变量名形式的字段名
#可以同时传递位置参数和关键字参数
print('这是一个关于{0}、{1}和{girl}的故事。'.format('小强','小梅',girl='静香'))
#输出结果
#这是一个关于小强、小梅和静香的故事。#但是关键字参数必须位于位置参数之后
#print('这是一个关于{0}、{1}和{girl}的故事。'.format('小强',girl='静香','小梅'))
#输出结果
#SyntaxError: positional argument follows keyword argument#数字也可以省略
print('这是一个关于{}、{}和{girl}的故事。'.format('小强','小梅',girl='静香'))#但是省略字段名不能和数字形式的字段名同时出现
print('这是一个关于{}、{1}和{girl}的故事。'.format('小强','小梅',girl='静香'))
#输出结果
#ValueError: cannot switch from automatic field numbering to manual field specification
2.5使用元组和字典传参
str.format()方法还可以使用 *元组和**字典 的形式传参,两者可以混合使用。
位置参数、关键字参数、*元组和**字典也可以同时使用,但是要注意,位置参数要在关键字参数前面,*元组要在**字典前面。
#使用元组传参
infos = '花木兰',66,'继承者'
print('我是{},身价{}亿。'.format(*infos))
#输出结果
#我是花木兰,身价66亿。print('我是{2},身价{1}亿。'.format(*infos))
#输出结果
#我是继承者,身价66亿。#使用字典传参
venom = {'name':'蜘蛛侠','weakness':'火'}
print('我是{name},我怕{weakness}。'.format(**venom))
#输出结果
#我是蜘蛛侠,我怕火。#同时使用元组和字典传参
hulk = '绿巨人','拳头'
captain = {'name':'美国队长','weapon':'盾'}
print('我是{},我怕{weapon}。'.format(*hulk,**captain))
print('我是{name},我怕{1}。'.format(*hulk,**captain))
#输出结果
#我是绿巨人,我怕盾。
#我是美国队长,我怕拳头。#同时使用位置参数、元组、关键字参数、字典传参
#注意:位置参数要在关键字参数前面
# *元组要在**字典前面
tup = '鹰眼',
dic = {'weapon':'箭'}
text = '我是{1},我怕{weakness}。我是{0},我用{weapon}。'
text = text.format(*tup,'黑寡妇',weakness = '男人', **dic)
print(text)
#输出结果
#我是黑寡妇,我怕男人。我是鹰眼,我用箭。
3 复合字段名
- 同时使用了数字和变量名两种形式的字段名就是复合字段名。
- 复合字段名 支持两种操作符:
- . 点号
- []中括号
3.1 使用.点号
传递位置参数
- 替换字段形式:{数字.属性名}
- 只有一个替换字段的时候可以省略数字
class Person(object):def __init__(self,name,age,gender):self.name = nameself.age = ageself.gender = gender
p = Person('lisi',19,'female')
print('姓名是{0.name},年龄是{0.age},性别是{0.gender}'.format(p))
print('姓名是{.name}'.format(p)) #只有一个替换字段时,可以省略数字
3.2 使用[]中括号
- 用列表传递位置参数
- 用元组传递位置参数
- 用字典传递位置参数
#中括号用法,用列表传递位置参数
infos = ['阿华',9527]
food = ['金银花','爆米花']
print('我叫{0[0]},警号{0[1]},爱吃{1[0]}。'.format(infos,food))
#输出结果
#我叫阿华,警号9527,爱吃金银花。#中括号用法:用元组传递位置参数
food = ('僵尸','脑子')
print('我叫{0[0]},年龄{1},爱吃{0[1]}。'.format(food,66))
#输出结果
#我叫僵尸,年龄66,爱吃脑子。# 中括号用法:用字典传递位置参数
dic = dict(name='阿星', pid=9527)
print('我是{[name]}!'.format(dic))
# 多个替换字段,不能省略数字
print('我是{0[name]},警号{0[pid]}。'.format(dic))
#输出结果
#我是阿星!
#我是阿星,警号9527。
4 转换字段
转换字段 conversion field 的取值有三种,前面要加!:
- s:传递参数之前先对参数调用str()
- r:传递参数之前先对参数调用repr()
- a:传递参数之前先对参数调用ascii()
ascii()函数类似repr()函数,返回一个可以表示对象的字符串。但是对于非ASCII字符,使用\x,\u或者\u转义。
#转换字段
print('I am {!s}!'.format('Bruce Lee 李小龙'))
print('I am {!r}!'.format('Bruce Lee 李小龙'))
print('I am {!a}!'.format('Bruce Lee 李小龙'))
#输出结果
# I am Bruce Lee 李小龙!
# I am 'Bruce Lee 李小龙'!
# I am 'Bruce Lee \u674e\u5c0f\u9f99'!