
Python 中 str.format() 方法详解
3.2
3.3
发布日期:2021-05-07 17:48:40
浏览次数:26
分类:技术文章
本文共 9241 字,大约阅读时间需要 30 分钟。
Python 中 str.format() 方法详解
转载请注明出处:https://blog.csdn.net/jpch89/article/details/84099277
文章目录
0. 参考资料
1. 术语说明
str.format()
方法通过字符串中的花括号{}
来识别替换字段replacement field
,从而完成字符串的格式化。- 替换字段 由字段名
field name
和转换字段conversion field
以及格式说明符format specifier
组成,即一般形式为{字段名!转换字段:格式说明符}
。 - 字段名分为简单字段名
simple field name
和复合字段名compound field name
。 - 而转换字段和格式说明符都是可选的。
2. 简单字段名
2.1 简单字段名的说明
简单字段名有三种写法:
- 省略不写
{}
- 数字
{十进制非负整数}
- 变量名
{合法的Python标识符}
2.2 省略字段名
花括号内省略字段名,传递位置参数。
- 替换字段形式:
{}
- 注意:花括号个数可以少于位置参数的个数,反之不然。
# 省略字段名传递位置参数print('我叫{},今年{}岁。'.format('小明', 18))"""我叫小明,今年18岁。"""# 花括号个数可以少于位置参数的个数print('我爱吃{}和{}。'.format('香蕉', '苹果', '大鸭梨'))"""我爱吃香蕉和苹果。"""# 花括号个数多于位置参数的个数则会报错# print('我还吃{}和{}。'.format('西红柿'))"""IndexError: tuple index out of range"""
2.3 数字形式的简单字段名
可以通过数字形式的简单字段名传递位置参数。
- 数字必须是大于等于
0
的整数。 - 带数字的替换字段可以重复使用。
- 数字形式的简单字段名相当于把
format
中的所有位置参数整体当作一个元组,通过字段名中的数字进行取值。 - 即
{0}
等价于tuple[0]
,所以花括号内的数字不能越界。
# 通过数字形式的简单字段名传递位置参数print('身高{0},家住{1}。'.format(1.8, '铜锣湾'))"""身高1.8,家住铜锣湾"""# 数字形式的简单字段名可以重复使用。print('我爱{0}。\n她今年{1}。\n{0}也爱我。'.format('阿香', 17))"""我爱阿香。她今年17。阿香也爱我。"""# 体会把所有位置参数整体当成元组来取值print('阿香爱吃{1}、{3}和{0}。'.format( '榴莲', '臭豆腐', '皮蛋', '鲱鱼罐头', '螺狮粉'))"""阿香爱吃臭豆腐、鲱鱼罐头和榴莲。"""# 尝试一下越界错误# print('{1}'.format('错误用法'))"""IndexError: tuple index out of range"""
2.4 变量名形式的简单字段名
使用变量名形式的简单字段名传递关键字参数。
- 关键字参数的位置可以随意调换。
# 使用变量名形式的简单字段名传递关键字参数print('我大哥是{name},今年{age}岁。'.format(name='阿飞', age=20))"""我大哥是阿飞,今年20岁。"""# 关键字参数的顺序可以随意调换print('我大哥是{name},今年{age}岁。'.format(age=20, name='阿飞'))"""我大哥是阿飞,今年20岁。"""
2.5 简单字段名的混合使用
- 混合使用数字形式和变量名形式的字段名,可以同时传递位置参数和关键字参数。
- 关键字参数必须位于位置参数之后。
- 混合使用时可以省略数字。
- 省略字段名
{}
不能和数字形式的字段名{非负整数}
同时使用。
# 混合使用数字形式和变量名形式的字段名# 可以同时传递位置参数和关键字参数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.6 使用元组和字典传参
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 复合字段名的说明
- 同时使用了数字和变量名两种形式的字段名就是复合字段名。
- 复合字段名支持两种操作符:
[]
方括号.
点号
3.2 .
点号的使用
传递位置参数
- 替换字段形式:
{数字.属性名}
- 只有一个替换字段的时候可以省略数字
# 复合字段名中使用点号传递对象属性class Person: def __init__(self, name, addr): self.name = name self.addr = addrp = Person('辣妹子', '重庆')# 点号用法:传递位置参数print('我是{0.name},家在{0.addr}。'.format(p))"""我是辣妹子,家在重庆。"""# 当只有一个替换字段的时候可以省略数字print('{.name}辣!'.format(p))"""辣妹子辣!"""# 试试传递文件对象的属性f = open('out.txt', 'w')print('文件名为:{.name}'.format(f))f.close()"""文件名为:out.txt"""
传递关键字参数
- 替换字段形式:
{关键字参数名.属性名}
# 点号用法:传递关键字参数print('我是{girl.name},家在{girl.addr}。'.format(girl=p))# 和上一句等价print('我是{p.name},家在{p.addr}。'.format(p=p))"""我是辣妹子,家在重庆。我是辣妹子,家在重庆。"""
3.3 []
方括号的使用
传递位置参数
- 用列表传递位置参数
- 用元组传递位置参数
- 用字典传递位置参数
# 方括号用法:用列表传递位置参数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。"""
传递关键字参数
- 用列表传递关键字参数
- 用元组传递关键字参数
- 用字典传递关键字参数
# 方括号用法:传递关键字参数names = ['皮卡丘']dic = { 'name': '妙蛙花'}skills = ('十万伏特', '飞叶快刀')text = '我是{names[0]},我会{skills[0]}。我是{dic[name]},我会{skills[1]}。'text = text.format(names=names, skills=skills, dic=dic)print(text)"""我是皮卡丘,我会十万伏特。我是妙蛙花,我会飞叶快刀。"""
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'!"""
5. 格式说明符
- 在替换字段中,格式说明符前面有一个冒号
:
:{字段名!转换字段:格式说明符}
- 其中格式说明符本身可以是一个字段名,比如:
print('{0:{1}}'.format(3.14159, '.4f'))"""3.1416"""
5.1 标准格式说明符的格式
- 如果不通过重写
__format__
方法来进行自定义的话,标准格式说明符的形式如下。其中方括号是可选的。[[fill]align][sign][#][0][width][grouping_option][.precision][type]
- 中文形式可以写作:
[[填充]对齐方式][正负号][#][0][宽度][分组选项][.精度][类型码]
5.2 填充与对齐方式
填充:
- 只能是一个字符
- 不指定默认用空格填充
- 如果指定填充字符,则必须要同时指定对齐方式
对齐方式的取值:
<
:左对齐>
:右对齐^
:居中=
:在正负号(如果有的话)和数字之间填充,该对齐选项仅对数字类型有效。 它可以输出类似+0000120
这样的字符串。
注意:
- 如果不给定最小宽度
width
,对齐方式毫无意义。
5.3 正负号
- 正负号选项仅对数字类型生效
- 取值有三种:
+
正数前面添加正号,负数前面添加负号-
仅在负数前面添加负号(默认行为)空格:正数前面需要添加一个空格,以便与负数对齐
# 正负号print('{:哈=+8.2f}'.format(3.14159))print('{:哈=+8.2f}'.format(-3.14159))print('{:哈=+8.2f}'.format(0))print('{:哈=+8.2f}'.format(-0))"""+哈哈哈3.14-哈哈哈3.14+哈哈哈0.00+哈哈哈0.00"""
5.4 # 号
#
号:
- 给u二进制数加上
0b
前缀 - 给八进制数加上
0o
前缀 - 给十六进制数加上
0x
前缀
5.5 最小宽度
最小宽度 width
:
- 如果不指定,最小字段宽度由内容决定,与内容相等
- 如果最小宽度前面有一个前导
0
,意味着用0
填充 这等价于指定了0=
的填充和对齐方式
5.6 分组选项
分组选项 grouping_option
的取值有两种:
- 逗号
,
:使用逗号对数字以千为单位进行分隔。n
类型的数字可以使用本地化的分隔符。
原因可能是中文没有数字分隔符
n
类型在本机无法使用分组选项,
# n 类型使用本地化的分组选项 ,# 此项报错,我怀疑是因为中文没有数字的分隔符# print('数字:{0:,n}'.format(6666))"""ValueError: Cannot specify ',' with 'n'."""# 使用 d 类型确实是可以的print('数字:{0:,d}'.format(6666))"""数字:6,666"""
- 下划线
_
:使用下划线对浮点数和d
类型的整数以千为单位进行分隔。对于b
、o
、x
和X
类型,每四位插入一个下划线,其他类型都会报错。
# 分组选项 _ 作用于 b 类型print('数字:{0:_b}'.format(0b100111011))"""数字:1_0011_1011"""# 分组选项 _ 作用于 o 类型print('数字:{0:_o}'.format(0o426754316))"""数字:4_2675_4316"""# 分组选项 _ 作用于 x 类型print('数字:{0:_x}'.format(0x2a846e98d))"""数字:2_a846_e98d"""# 分组选项 _ 作用于 X 类型print('数字:{0:_X}'.format(0X2a846e98d))"""数字:2_A846_E98D"""# 分组选项 _ 作用于其他类型(比如 n 类型)# print('字符串:{0:_n}'.format(1234567))"""ValueError: Cannot specify ',' with 'n'."""
5.7 精度
精度:
- 精度指定了小数点后面要展示多少位小数
- 对于非数字类型,精度指定了最大字段宽度
- 整数类型不能指定精度
# 对于非数字类型,精度指定最大字段宽度print('{0:.3}'.format('哇哈哈哈哈哈'))"""哇哈哈"""# 整数类型不能指定精度print('{:.3d}'.format(666))"""ValueError: Precision not allowed in integer format specifier"""
5.8 类型码
类型码可以分为三大类:
- 字符串类型
- 整数类型
- 浮点数类型
5.8.1 字符串类型
s
字符串类型。这是字符串的默认类型,可以省略。None
不指定类型。同s
类型。
# s 类型print('{0:s}'.format('略略略'))# s 类型可以省略print('{0:}'.format('略略略'))"""略略略略略略"""
5.8.2 整数类型
b
二进制。
# b 类型:二进制print('{0:b}'.format(3))"""11"""
c
字符。把整数转换为相应的Unicode
字符,然后再打印。
# c 类型:把整数转换成 unicode 字符print('{:c}'.format(97))"""a"""
d
十进制整数。
# d 类型:十进制整数print('{:d}'.format(666))"""666"""
o
八进制数。
# o 类型:八进制数print('{:o}'.format(10))"""12
x
十六进制数,a
到f
小写。
# x 类型:十六进制数,a到f小写print('{:x}'.format(15))"""f"""
X
十六进制数,A
到F
大写。
# X 类型:十六进制数,A到F大写print('{:X}'.format(15))"""F"""
n
数字number
类型,与d
相同,只不过它会使用本地化的数字分隔符。
经试验,在本机为
n
类型指定任何分组选项(,
和_
)都会报错。ValueError: Cannot specify ',' with 'n'.
# n 类型:与d相同,会插入本地化的分隔符print('{:n}'.format(66666))# 经试验,本机无法为 n 指定任何分组选项(,_)# print('{:,n}'.format(66666))"""ValueError: Cannot specify ',' with 'n'."""# print('{:_n}'.format(66666))"""ValueError: Cannot specify ',' with 'n'."""
None
不指定类型,与d
相同。
5.8.3 浮点数类型
e
科学记数法,用e
来表示指数。默认精度为6
位
# e 类型:科学记数法# 默认精度为 6 位print('{:e}'.format(1234567.1234567))"""1.234567e+06"""
E
与e
相同,但是使用大写的E
表示指数。
# E 类型:与 e 相同,用大写 E 表示指数# 默认精度为 6 位print('{:E}'.format(1234567.1234567))# 修改精度为 10 位print('{:.10E}'.format(1234567.1234567))"""1.234567E+061.2345671235E+06"""
f
定点记法,默认精度为6
。
# f 类型# 默认精度为 6 位print('{:f}'.format(1234567.1234567))"""1234567.123457"""
F
定点记法,同f
,但是会把nan
转换成NAN
,把inf
转换成INF
# F 类型nan = float('nan')inf = float('inf')print('{:F}\n{:F}'.format(nan, inf))"""NANINF"""
g
通用general
格式。自动转换到e
或者f
格式,具体的转换规则在此省略。正无穷、负无穷、正零、负零和非数字分别显示为inf
,-inf
,0
,-0
,nan
。指定精度为0
时等价于精度为1
。默认精度为6
位。
# g 类型print('{:g}'.format(1234567.1234567))print('{:g}'.format(1234.1234))"""1.23457e+061234.12"""
G
通用general
格式。自动转换到E
或者F
格式,转换规则同上,相应表示方式换成大写。
# g 类型print('{:g}'.format(1234567.1234567))print('{:g}'.format(1234.1234))"""1.23457e+061234.12"""
n
数字number
类型。跟g
一样,只不过用本地化的分隔符来分隔数字。
# n 类型print('{:n}'.format(1234567.1234567))print('{:n}'.format(1234.1234))"""1.23457E+061234.12"""# 经试验,本机指定分组选项会报错# print('{:,n}'.format(1234.1234))"""ValueError: Cannot specify ',' with 'n'."""# print('{:_n}'.format(1234.1234))"""ValueError: Cannot specify ',' with 'n'."""
%
百分号类型。会将数字乘以100
,然后以f
定点fixed-point
格式显示,最后加上一个百分号%
。
# % 类型print('{:%}'.format(1))"""100.000000%"""
None
不指定类型。输出效果类似调用str()
函数。
6. 补充说明
- 输出花括号需要用花括号本身来转义
# 打印花括号需要使用花括号转义print('{ { {}}}'.format('张无忌'))"""{张无忌}"""
- 对象可以自定义格式说明符来替换标准格式说明符,比如
datetime
类。
from datetime import datetimeprint("Today is: {0:%a %b %d %H:%M:%S %Y}".format(datetime.now()))"""今天是:Thu Nov 15 13:05:09 2018"""
完成于 2018.11.15
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年04月05日 12时13分58秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
汉诺塔 C++实现【STL stack】
2019-03-04
数据结构——链表
2019-03-04
[数据结构与算法]链表逆置与遍历
2019-03-04
CommonJs
2019-03-04
Unicode编码和Base64编码
2019-03-04
html基础
2019-03-04
ICMP网际控制报文协议
2019-03-04
[编程题]Course List for Student (25)
2019-03-04
Python【面向对象】1
2019-03-04
【Python】面向对象,封装
2019-03-04
接口又是个啥?
2019-03-04
二叉树的基础练习题代码
2019-03-04
(JAVA小白必看)小白IDEA的安装与配置
2019-03-04
SpringMVC模板代码
2019-03-04
C++ Primer学习笔记——第2章 变量和基本数据类型
2019-03-04
5.11 TEST1
2019-03-04
6.14 阶段考试
2019-03-04
牛客IOI周赛19-普及组
2019-03-04
2020牛客NOIP赛前集训营-普及组(第四、五场)
2019-03-04