Python字符串格式化

Python字符串格式化

引言

字符串格式化是我们在使用Python中经常用到的功能。Python为我们提供了四种格式化字符串的方法,分别是%运算符字符串format方法格式化字符串字面值以及模板字符串

%运算符

%运算符提供了一种printf风格的字符串格式化,它的用法跟C语言中的printf十分相似。先来看一个例子:

1
2
s = "我叫%s, 今年%d岁。" % ("小明", 18) # 我叫小明, 今年18岁。
print(s)

使用%运算符格式化字符串的语法是format % valuesformat是一个字符串,values可以是一个对象元组字典,format中会有若干个’%’开头的标记转换符,例如“%d”代表一个整数,“%s”代表一个字符串,这些标记转换符会被values中的条目替换。

value是一个元组时,需要每个转换符与value中的条目一一对应,可以为标记转换符添加映射键,value的类型应为字典。例如:

1
2
s = "我叫%(name)s, 今年%(age)d岁。" % {"name": "小明", "age": 18}
print(s)

转换标记符包含两个或更多字符并具有以下组成,且必须遵循此处规定的顺序:

  1. ‘%’ 字符,用于标记转换符的起始。
  2. 映射键(可选),由加圆括号的字符序列组成 (例如 (somename))。
  3. 转换旗标(可选),用于影响某些转换类型的结果。
  4. 最小字段宽度(可选)。 如果指定为 ‘*’ (星号),则实际宽度会从 values 元组的下一元素中读取,要转换的对象则为最小字段宽度和可选的精度之后的元素。
  5. 精度(可选),以在 ‘.’ (点号) 之后加精度值的形式给出。 如果指定为 ‘*’ (星号),则实际精度会从 values 元组的下一元素中读取,要转换的对象则为精度之后的元素。
  6. 长度修饰符(可选)。
  7. 转换类型。

以下是转换符列表:

转换符 含义
‘d’ 有符号十进制整数。
‘i’ 有符号十进制整数。
‘o’ 有符号八进制数。
‘u’ 过时类型 – 等价于 ‘d’。
‘x’ 有符号十六进制数(小写)。
‘X’ 有符号十六进制数(大写)。
‘e’ 浮点指数格式(小写)。
‘E’ 浮点指数格式(大写)。
‘f’ 浮点十进制格式。
‘F’ 浮点十进制格式。
‘g’ 浮点格式。 如果指数小于 -4 或不小于精度则使用小写指数格式,否则使用十进制格式。
‘G’ 浮点格式。 如果指数小于 -4 或不小于精度则使用大写指数格式,否则使用十进制格式。
‘c’ 单个字符(接受整数或单个字符的字符串)。
‘r’ 字符串(使用 repr() 转换任何 Python 对象)。
‘s’ 字符串(使用 str() 转换任何 Python 对象)。
‘a’ 字符串(使用 ascii() 转换任何 Python 对象)。
‘%’ 不转换参数,在结果中输出一个 ‘%’ 字符。

转换标志列表:

标志 含义
‘#’ 值的转换将使用“替代形式”(具体定义见下文)。
‘0’ 转换将为数字值填充零字符。
‘-‘ 转换值将靠左对齐(如果同时给出 ‘0’ 转换,则会覆盖后者)。
‘ ‘ (空格) 符号位转换产生的正数(或空字符串)前将留出一个空格。
‘+’ 符号字符 (‘+’ 或 ‘-‘) 将显示于转换结果的开头(会覆盖 “空格” 旗标)。

Python官方文档并不建议我们使用这种方法,因为这种方法不仅需要标识转换符与value一一对应,而且还不能正确格式化元组列表等类型。所以,在Python中使用格式化字符串建议使用以下三种方法。

字符串format方法

例子:

1
2
s = "{} + {} = {}".format(1, 2, 3) # 1 + 2 = 3
print(s)

format会将参数依次替换字符串中的{}并返回一个新的str对象。如果需要输出{}需要用两层花括号({{}})

“{}”可以具有位置参数,format方法将会用指定位置的参数代替花括号。如果使用位置参数,那么所有的花括号中都必须有位置参数。例如:

1
2
s = "{1} + {0} = {2}".format(1, 2, 3)
print(s)

“{}”中还可以具有关键字参数

1
2
s = "我叫{name}, 今年{age}岁。".format(name="小明", age=18)
print(s)

位置参数和关键字参数可以混用。

可以使用**传递字典作为关键字参数:

1
2
3
table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
# Jack: 4098; Sjoerd: 4127; Dcab: 8637678

还可以在花括号中添加格式化参数,详见格式字符串语法

格式化字符串字面值

Python3.6新增加了格式化字符串字面值的特性,可以方便的格式化字符串。

例子:

1
2
3
4
name = "小明"
age = 18
print(f"我叫{name}, 今年{age}岁。")
# 我叫小明, 今年18岁。

当我们在一个字符串前标注一个'f''F'时,Python解释器就认为这个字符串是一个格式化字符串字面值。在这个字符串中使用“{}”将一个变量或表达式括起来,Python就会用变量或表达式的内容替换“{}”。格式化字符串字面值还可以使用格式说明符,用法与str.format相同:

1
2
price = 12.567
print(f"苹果的价格是{price:.2f}") # 苹果的价格是12.57

转换符!s!r!a分别调用strreprascii对表达式进行求值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Student:
def __init__(self, name: str = "小明", age: int = 18):
self.name: str = name
self.age: int = age

def __str__(self):
return self.name + " " + str(self.age) + " __str__"

def __repr__(self):
return self.name + " " + str(self.age) + " __repr__"


print(f"{Student()!s}\n{Student()!r}\n{Student()!a}")
# 小明 18 __str__
# 小明 18 __repr__
# \u5c0f\u660e 18 __repr__

格式表达式中不能有反斜杠,否则会报错。即便未包含表达式,格式字符串字面值也不能用作文档字符串。

模板字符串

Python提供的Template类也可以用来格式化字符串,它位于string包。使用Template类时,实现实例化一个Template对象。然后调用substitutesafe_substitute用传入的参数替换模板字符串中的变量:

1
2
3
4
5
t = Template("我叫$name, 今年$age岁。")
s = t.substitute(name="小明", age=18)
print(s)
s = t.substitute({"name": "小明", "age": 18})
print(s)

$identifier为替换占位符,它会匹配一个名为 “identifier” 的映射键。如果映射键有歧义可以使用花括号区分。否则Python将匹配尽可能多的字符:

1
2
3
print(Template("$ab").substitute(a=1, ab=2))  # 2
print(Template("${a}b").substitute(a=1, ab=2)) # 1b
print(Template("${ab}").substitute(a=1, ab=2)) # 2

substitutesafe_substitute可以接受关键字参数或者字典。这两个方法的区别在于,模板字符串中的一个标识符在传入方法的参数中没有条目与之对应时,substatute会抛出ValueError,而safe_substitute会保留$和标识符而不进行替换。

想要在字符串中保留$可以用$$转义。

参考

  1. python字符串格式化深入详解(四种方法)

  2. printf 风格的字符串格式化

  3. string — 常见的字符串操作


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!