第3.11节 Python强大的字符串格式化新功能:format字符串格式化的格式控制

                                            第3.11节 format字符串格式化的格式控制
一、    引言
上节介绍了四种format进行字符串格式化的方法,但都只介绍了真实值与格式符的位置映射关系,而没有介绍诸如宽度、对齐方式、精度控制等控制每个真实值显示格式的内容。本节就介绍怎么进行字符串格式化的格式控制,这种格式控制的要素在format格式化中称为“格式说明符”。
在前面章节介绍了“格式符”(也称为“替换字段”、“转换说明符”),格式说明符是格式符的一个子串,专门用于控制输出格式。

二、    格式符内容
在format字符串格式化中,“格式符”中大括号(大括号就是占位符)及其内的内容组成如下:
格式符:{[字段名][!转换标志][: 格式说明符]}
1.    字段名:索引或标识符,可以是数字(即索引)、变量、变量.属性、变量[索引]、变量[键值],指出要设置哪个真实值并使用结果来替换该字段。请见案例部分;
2.    转换标志:跟在叹号后面的单个字符。当前支持的字符包括r(表示repr)、s(表示str)和a(表示ascii)。如果你指定了转换标志,将不使用对象本身的格式设置机制,而是使用指定的函数将对象转换为字符串,再做进一步的格式设置。上述三个标志(s、r和a)指定分别使用str、repr和ascii进行转换。关于这三种类型,老猿没有深入研究,我们来以:s='20190301 班 小明 同学,小名:小明,总分:597.5'这个字符串来进行测试:
1)    ascii(s)输出:带双引号的编码串
"'20190301 \u73ed \u5c0f\u660e \u540c\u5b66,\u5c0f\u540d\uff1a\u5c0f\u660e\uff0c\u603b\u5206:597.5'"
2)    repr(s)输出:在原输入前加了双引号
"'20190301 班 小明 同学,小名:小明,总分:597.5'"
3)    str(s):与s值一样。
函数str通常创建外观普通的字符串版本(没有对输入字符串做任何处理)。函数repr尝试创建给定值的Python表示(这里是一个字符串字面量,老猿暂时没有理解这句话,可能是字符串内容在Python中的内存存储?)。函数ascii创建只包含ASCII字符的表示(老猿理解就是把不是ascii码的字符转换成双字节编码展示)。

3.    格式说明符:跟在冒号后面的微型格式指定语言表达式。格式说明符让我们能够详细地指定最终的格式,包括格式类型(如字符串、浮点数或十六进制数),字段宽度和数的精度,如何显示符号和千位分隔符,以及各种对齐和填充方式。
语法:[[填充符]对齐方式][符号][#][0][宽度][分组选项][.精度][类型]
1)    所有格式说明符字段都是可选项;
2)    填充符:可以是任何字符,将在显示内容宽度比设定宽度短时用填充符补齐;
3)    对齐方式:“<”符号表示左对齐、“>”表示右对齐,“^”表示居中对齐,“=”用于带符号的数字对齐时,在符号和数字之间补充填充符,当没有指定填充符时,使用默认填充符(空格),但如果数字的宽度前有0时,0将替换默认填充符。
关于使用等号对数字对齐的举例:
'{:=+9}'.format(12345)  #结果为:'+   12345'
'{:=+09}'.format(12345) #结果为:'+00012345'
'{:*=+09}'.format(12345) #结果为:'+***12345'
4)    符号:仅用于数字,“+”表示在数字前加正号和负号,“-”表示只有负数加负号,这是默认的方式,空格表示在正数前加一个空格,负数前加一个减号
5)    #:表示在转换成字符串时使用“替代形式”。此选项仅对integer、float、complex和decimal类型有效。对于整数,使用二进制、八进制或十六进制输出时,此选项会将前缀“0b”、“0o”或“0x”分别添加到输出值。对于浮点数、复数和小数,替换形式会导致转换结果(即使后面没有数字)始终包含小数点字符。此外,对于“g”和“g”转换,尾随零不会从结果中移除。
6)    0:当没有指定填充符时,如果数字的宽度前有“0”时,“0”将替换默认填充符;
7)    宽度:数据输出占用的宽度,当实际输出大于该宽度时按实际宽度输出,此时对齐方式和填充符不起作用;
8)    分组选项:用于数字,“,”选项表示使用逗号作为千位分隔符。“_”选项表示对浮点类型和整型表示类型“d”的千位分隔符使用下划线。对于整数表示类型“B”、“O”、“X”和“x”,下划线将每4位插入一次。对于其他类型,指定此选项是错误的;
9)    精度:精度对于格式为“f”和“F”的浮点值,表示小数点后应显示多少位数,对于格式为“g”或“G”的浮点值,小数点前后应显示多少位数。对于非数字类型,字段指示最大字段大小——换句话说,字符串的精度小于字符串长度时,直接截取前面长度。整数值不允许精度。注意精度前要带点。
10)    类型:说明真实值的类型
类型           含义
b          将整数表示为二进制数
c          将整数解读为Unicode码点
d          将整数视为十进制数进行处理,这是整数默认使用的说明符
e          使用科学表示法来表示小数(用e来表示指数)
E          与e相同,但使用E来表示指数
f          将小数表示为定点数
F          与f相同,但对于特殊值(nan和inf),使用大写表示
g          自动在定点表示法和科学表示法之间选择。默认用于小数,在默认情况下至少有1位小数
G          与g相同,但使用大写来表示指数和特殊值
n          与d相同,但插入随区域而异的数字分隔符
o          将整数表示为八进制数
s          保持字符串的格式不变,这是默认用于字符串的说明符
x          将整数表示为十六进制数并使用小写字母
X          与x相同,但使用大写字母
%          将数表示为百分比值(乘以100,按说明符f设置格式,再在后面加上%)
None           当没有指定类型时,字符串按s方式,数字按d方式,浮点数按g方式
三、    格式符举例
student={'name':'小明','class':'20190301','score':597.5}
1.    s1='{st[class]}班{st[name]:_>4}总分:{st[score]:0>+6.1f}'.format(st=student)
执行结果:s1= '20190301班__小明总分:+597.5'
2.    s2='{st[class]}班{st[name]!r:_>4}总分:{st[score]:0>+6.1f}'.format(st=student)
指定名字转换标记为r,执行结果:s2="20190301班'小明'总分:+597.5"
3.    s3=f"{ student ['classno']}班{ student ['name']:_>4}总分:{ student ['score']:0>+6.1f}"
执行结果:'20190301班__小明总分:+597.5',注意这里的字典键值加了单引号。
4.    '{:*>+#10_}'.format(123456)   #结果为'**+123_456'
5.    '{:*>+#10_b}'.format(123456) #结果为'+0b1_1110_0010_0100_0000'
6.    '{:*>+#10_o}'.format(123456) #结果为'+0o36_1100
7.    '{:*>+#10_x}'.format(123456) #结果为'*+0x1_e240'

以上例子就不补充解释了,大家对照前面的说明自己分析一下。

本节详细介绍了格式化字符串中的格式符的组成及每部分的含义,并举例进行说明,内容比较多,不容易记住,请大家先理解,具体格式实际使用时进行资料速查就可以了。最后补充介绍一下模块string中几个与字符串相关的常量和一个函数:
string.digits:包含数字0~9的字符串。
string.ascii_letters:包含所有ASCII字母(大写和小写)的字符串。
string.ascii_lowercase:包含所有小写ASCII字母的字符串。
string.printable:包含所有可打印的ASCII字符的字符串。
string.punctuation:包含所有ASCII标点字符的字符串。
string.ascii_uppercase:包含所有大写ASCII字母的字符串。虽然说的是ASCII字符,但值实际上是未解码的Unicode字符串。
string.capwords(s[, sep]) 使用split根据sep拆分s,将每项的首字母大写,再以SPLIT为分隔符将它们合并起来,如:
string.capwords(s,'/')
'/Usr/Var/Tempdirectory'
到本节为止,字符串的内容共介绍了六节内容,基本上字符串相关的内容就全介绍完了,希望大家好好理解。


截止到本节,Python的数据类型基础知识就介绍完了。这阵子老猿是每天至少写一篇博客,都是基于前期学习的知识基础上整理出来的内容,后后面准备介绍的生成器、迭代器、列表解析等内容部分还在深入研究和总结,后面更新将放慢节奏,但至少保证每周一节内容的更新,同时个人认为后面这些内容属于数据类型进阶的内容,将新开一章进行介绍。

    老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。 
    欢迎大家批评指正,谢谢大家关注!

原文地址:https://www.cnblogs.com/LaoYuanPython/p/11087732.html