本文翻译自 printf-style String Formatting 官方文档
转载请注明出处:https://www.jianshu.com/u/5e6f798c903a
Note: printf-style 的格式化操作存在一些缺陷,会导致许多常见的错误(例如无法正确显示元组和字典)。
改用以下三种的字符串格式化方式,可避免这些错误。
字符串对象拥有一个独特的内置运算符: %
(modulo),使用效果类似于 C 语言中 sprintf()
函数。
printf-style 有如下两种形式:
-
第一种形式:
<format string> % <datum>
,其中的<format string>
只有一个参数,此处的<datum>
必须是单个非元组(non-tuple )对象。aList = [1, 2, 3] aDict = dict(a=1, b=2, c=3) aSingleTuple = (1,) # 可以是仅有一个元素的元组 aTuple = (1, 2, 3) print("%s" % aList) print("%s" % aDict) print("%s" % aSingleTuple) # print("%s" % aTuple) 会抛出异常
输出
[1, 2, 3] {'a': 1, 'b': 2, 'c': 3} 1
-
第二种形式:
<format string> % [<datum_1>,...,<datum_n>]
,其中的<format string>
有 n 个参数,[<datum_1>,...,<datum_n>]
必须是有 n 个元素的元组,或有 n 个键值对的映射对象(如字典)aTuple = (1, 2, 3) aDict = dict(a=1, b=2, c=3) # 映射对象 print("%s %s %s" % aTuple) print('%(language)s has %(number)03d quote types.' % {'language': "Python", "number": 2}) print("%(a)s %(b)s %(c)s" % aDict) print("%s %s %s" % ("a", "b", "c")) # 不能直接给出参数,必须打包到数组中,如下代码会抛出异常 # print("%s %s %s" % "a", "b", "c")
输出
1 2 3 Python has 002 quote types. 1 2 3 a b c
转换说明符
<format string>
中的参数被称作转换说明符(conversion specifier)。
转换说明符中至少包含两个字符,如 %s
。
转换说明符的排列顺序:
%[Mapping_key][Conversion_flags][Minimum_field_width][.Precision][Length_modifier][Conversion_type]
转换说明符中相关组件(components)的描述如下:
-
%
标识转换说明符的起点 -
mapping_key
(可选),由带括号的字符序列组成,如(somename)
。当<datum>
是字典(或其它映射类型)时,则必须使用mapping_key
,并用mapping_key
表示字典中相应的key
(这种情况下,转换说明符中不会出现*
,因为*
需要<datum>
是序列类型)。aDict = dict(a=1, b=2, c=3) print("%(b)s %(a)s " % aDict) # 不必使用所有key,顺序也可以变化 print('%(language)s has %(number)03d quote types.' % {'language': "Python", "number": 2}) # 输出:2 1 # 输出:Python has 002 quote types.
-
Conversion_flags
(可选),会影响某些装换类型(conversion types)的结果。 -
Minimum_field_width
(可选)。如果将Minimum_field_width
设置为'*'
(asterisk),那么需要将实际的width
值放置在对应的<datum>
之前。如果.precision
也使用了*
,那么<datum>
应位于width
值和.precision
值之后。print("%*s,%*s,%s" % (4, "a", 4, "b", "c")) # 输出: a b c
-
.Precision
(可选),精度值跟在.
(dot) 之后。如果将.Precision
设置为'*'
(asterisk),那么需要将实际的精度值放置在对应的<datum>
之前。import math print("%.*f" % (2, math.pi)) # 输出:3.14
-
Length_modifier
(可选) -
Conversion_type
Conversion_flags
Conversion_flags
字符含义如下:
Flag | Meaning |
---|---|
'#' |
使用替代形式(alternate form) 显示转换后的内容,在本节的Notes中会详细阐述 |
'0' |
在数值左侧使用 0 进行填充,而不是默认的空格。 |
'-' |
将转换后的内容在给定的字段宽度内左对齐,默认是右对齐(如果 '-' 和 '0' 同时存在,'-' 会覆盖 '0' )。如果转换后的内容大于给定的字段宽度,则不进行对齐。 |
' ' |
在正数前插入一个空格 |
'+' |
在正数前插入 '+' (会覆盖 ' ' 标记),负数会默认显示负号 |
>>> import math
# '0' 演示
>>> "%06.2f" % math.pi
'003.14'
# ‘-’ 演示
>>> "%-6s" % "Hi!"
'Hi! '
>>> "%-06.2f" % math.pi
'3.14 '
Length_modifier
虽然可以添加 length 修饰符 (h
, l
, 或 L
) ,但该修饰符会被 Python 忽略。
原因是 Python 并不需要该修饰符,所以在 Python 中 %ld
与 %d
完全等价。
Conversion_type
Conversion_type
字符含义如下
Conversion | Meaning | Notes |
---|---|---|
'd' |
有符号十进制整数 | |
'i' |
有符号十进制整数 | |
'o' |
有符号八进制整数 | (1) |
'u' |
废弃的类型,含义与 'd' 相同 |
(6) |
'x' |
有符号十六进制数(小写) | (2) |
'X' |
有符号十六进制数(大写) | (2) |
'e' |
指数格式的浮点数(小写) | (3) |
'E' |
指数格式的浮点数(大写) | (3) |
'f' |
小数格式的浮点数 | (3) |
'F' |
小数格式的浮点数 | (3) |
'g' |
浮点格式。如果指数小于 -4 或大于等于精度时,会采用 'e' 格式;否则采用小数格式的浮点数。 |
(4) |
'G' |
浮点格式。如果指数小于 -4 或大于等于精度时,会采用 'E' 格式;否则采用小数格式的浮点数。 |
(4) |
'c' |
单个字符(接受整数,或仅包含单个字符的字符串) | |
'r' |
String (使用 repr() 函数转换相应的 Python 对象). |
(5) |
's' |
String (使用 str() 函数转换相应的Python 对象). |
(5) |
'a' |
String (使用 ascii() 函数转换相应的Python 对象). |
(5) |
'%' |
不进行转换,会直接得到 '%'
|
关于 'g'
的示例:
# 格式化的默认精度是6位小数,所以当整数部分的长度大于等于7时,
# 便会采用指数形式
print("%g" % 1234567)
print("%.2g" % 1234)
# 指数小于-4,也会采用指数形式
print("%g" % 0.000023456789)
输出
1.23457e+06
1.2e+03
2.34568e-05
Notes:
-
如果使用替代形式(alternate form) ,也就是
'#'
标识,会在第一个数字前插入八进制标识符 ('0o'
) -
如果使用替代形式(alternate form) ,也就是
'#'
标识,会在第一个数字前插入十六进制标识符 ('0x'
or'0X'
) -
如果使用替代形式(alternate form) ,也就是
'#'
标识,会导致结果始终包含小数点,即使小数点后没有数字。
精度(precision)用于确定小数点后的有效位数,默认是 6 位小数。>>> "%#.0f" % 2 '2.' >>> "%.0f" % 2 '2' >>> "%#f" % 2 '2.000000' >>> "%f" % 2 '2.000000'
-
如果使用替代形式(alternate form) ,也就是
'#'
标识,会导致结果始终包含小数点,即使小数点后没有数字。
精度(precision)用于确定小数点后的有效位数,默认是 6 位小数。>>> "%#.0g" % 0.00002 '2.e-05' >>> "%.0g" % 0.00002 '2e-05' >>> "%#g" % 0.00002 '2.00000e-05'
-
如果精度(precision)值为
N
,则会截取结果的前N
个字符。>>> "%.4s" % '1234567' '1234' >>> "%.4r" % '1234567' "'123" >>> "%.4a" % '1234567' "'123"
-
参考 PEP 237.
因为 Python 的字符串有明确的长度,因此 %s
转换不会假定字符串以 \0
结尾。
Changed in version 3.1:对绝对值超过 1e50 的值进行 %f
转换时,不会再将 %f
替换为 %g
。
网友评论