跳到主要内容

Python String format() 方法

format() 方法的语法是:

template.format(p0, p1, ..., k0=v0, k1=v1, ...)

这里,p0, p1,... 是位置参数,而 k0, k1,... 是带有值 v0, v1,... 的关键字参数。

并且,template 是格式代码和参数占位符的混合体。

String format() 参数

format() 方法可以接受任意数量的参数,但分为两种类型的参数:

  • 位置参数 - 参数列表,可以在花括号 {index} 内通过参数索引访问
  • 关键字参数 - 类型为 key=value 的参数列表,可以在花括号 {key} 内通过参数的键访问

String format() 返回值

format() 方法返回格式化后的字符串。

String format() 如何工作?

format() 方法读取传递给它的参数类型,并根据字符串中定义的格式代码进行格式化。

对于位置参数

位置参数

这里,参数 0 是字符串 "Adam",参数 1 是浮点数 230.2346。

注意: Python 中的参数列表从 0 开始。

字符串 "Hello {0}, your balance is {1:9.3f}" 是模板字符串。这包含了格式化的格式代码。

花括号仅仅是参数要放置的占位符。在上面的例子中,{0} 是 "Adam" 的占位符,{1:9.3f} 是 230.2346 的占位符。

由于模板字符串引用 format() 参数为 {0}{1},所以这些参数是位置参数。它们也可以不带数字作为 {} 引用,Python 内部会将它们转换为数字。

内部处理方式:

  • 由于 "Adam" 是第 0 个参数,它被放在 {0} 的位置。因为 {0} 不包含其他格式代码,所以不执行其他操作。
  • 但对于第 1 个参数 230.2346 来说,不是这样。这里,{1:9.3f} 将 230.2346 放在其位置,并执行 9.3f 操作。
  • f 指定格式处理的是浮点数。如果没有正确指定,将会出错。
  • 点号前的部分(9)指定数字(230.2346)可以占用的最小宽度/填充。在这种情况下,230.2346 被分配了至少 9 个位置,包括点号。 如果没有指定对齐选项,则它将被对齐到剩余空间的右侧。(对于字符串,则对齐到左侧。)
  • 点号后的部分(3)截断小数部分(2346)至给定数字。在这个案例中,2346 在 3 位之后被截断。 剩余数字(46)被四舍五入,输出结果为 235。

对于关键字参数

关键字参数

我们使用了上面的相同示例来展示关键字参数和位置参数之间的区别。

这里,我们不仅使用了参数,还使用了参数的键值对。即,name="Adam" 和 blc=230.2346。

由于这些参数通过它们的键名 {name}{blc:9.3f} 被引用,它们被称为关键字或命名参数。

内部处理方式:

  • 占位符 {name} 被 name 的值 "Adam" 替换。由于它不包含其他格式代码,"Adam" 被放置。
  • 对于参数 blc=230.2346,占位符 {blc:9.3f} 被值 230.2346 替换。但在替换之前,像前面的示例一样,它对其执行了 9.

3f 操作。 这输出 230.235。小数部分在 3 位之后被截断,剩余数字被四舍五入。同样,总宽度被分配 9,左侧留下两个空格。

使用 format() 进行基本格式化

format() 方法允许使用简单的占位符进行格式化。

示例 1:对默认参数、位置参数和关键字参数进行基本格式化

# 默认参数
print("Hello {}, your balance is {}.".format("Adam", 230.2346))

# 位置参数
print("Hello {0}, your balance is {1}.".format("Adam", 230.2346))

# 关键字参数
print("Hello {name}, your balance is {blc}.".format(name="Adam", blc=230.2346))

# 混合参数
print("Hello {0}, your balance is {blc}.".format("Adam", blc=230.2346))
```**输出**

```out
Hello Adam, your balance is 230.2346.
Hello Adam, your balance is 230.2346.
Hello Adam, your balance is 230.2346.
Hello Adam, your balance is 230.2346.

注意: 在混合参数的情况下,关键字参数必须始终在位置参数之后。

使用 format() 对数字进行格式化

您可以使用下面给出的格式化说明符对数字进行格式化:

数字格式化类型

类型含义
d十进制整数
c相应的 Unicode 字符
b二进制格式
o八进制格式
x十六进制格式(小写)
X十六进制格式(大写)
n与 'd' 相同。除了它使用当前区域设置的数字分隔符
e指数表示法。(小写 e)
E指数表示法(大写 E)
f固定点数显示(默认:6)
F与 'f' 相同。除了将 'inf' 显示为 'INF' 和 'nan' 显示为 'NAN'
g通用格式。将数字四舍五入到 p 个有效数字。(默认精度:6)
G与 'g' 相同。除了如果数字很大,则切换到 'E'。
%百分比。乘以 100 并在末尾加上 %。

示例 2:简单的数字格式化

# 整数参数
print("The number is:{:d}".format(123))

# 浮点数参数
print("The float number is:{:f}".format(123.4567898))

# 八进制、二进制和十六进制格式
print("bin: {0:b}, oct: {0:o}, hex: {0:x}".format(12))

输出

The number is: 123
The number is:123.456790
bin: 1100, oct: 14, hex: c

示例 3:带填充的整数和浮点数的数字格式化

# 带最小宽度的整数
print("{:5d}".format(12))

# 长度超过填充的数字不起作用
print("{:2d}".format(1234))

# 浮点数的填充
print("{:8.3f}".format(12.2346))

# 带最小宽度并用零填充的整数
print("{:05d}".format(12))

# 带零填充的浮点数
print("{:08.3f}".format(12.2346))

输出

     12
1234
12.235
00012
00012.235

这里,

  • 在第一个声明中,{:5d} 为整数参数分配了最小宽度 5。由于没有指定对齐方式,所以默认向右对齐。
  • 在第二个声明中,您可以看到宽度(2)小于数字(1234),因此左侧没有空间,但也不会截断数字。
  • 与整数不同,浮点数有整数部分和小数部分。定义给数字的最小宽度包括整数和小数部分以及“.”。
  • 在第三个声明中,{:8.3f} 将小数部分截断为 3 位,四舍五入最后 2 位。现在,数字 12.235 占用总宽度 8,左侧留下 2 个空格。
  • 如果您想用零填充剩余的位置,将零放在格式说明符前可以做到这一点。它适用于整数和浮点数:{:05d}{:08.3f}

示例 4:带符号的数字格式化

# 显示 + 符号
print("{:+f} {:+f}".format(12.23, -12.23))

# 仅显示 - 符号
print("{:-f} {:-f}".format(12.23, -12.23))

# 对 + 符号显示空格
print("{: f} {: f}".format(12.23, -12.23))

输出

+12.230000 -12.230000
12.230000 -12.230000
12.230000 -12.230000

使用对齐的数字格式化

当为数字分配一定宽度时,使用 <, ^, > 和 = 操作符进行对齐。

使用对齐的数字格式化

类型含义
<剩余空间左对齐
^剩余空间居中对齐
>剩余空间右对齐
=强制将符号 (+) (-) 移至最左端位置

示例 5:带左、右和居中对齐的数字格式化

# 带右对齐的整数
print("{:5d}".format(12))

# 带居中对齐的浮点数
print("{:^10.3f}".format(12.2346))

# 带零填充的左对齐整数
print("{:<05d}".format(12))

# 带居中对齐的浮点数
print("{:=8.3f}".format(-12.2346))

输出

   12
12.235
12000
- 12.235

注意: 对整数进行零填充的左对齐可能会导致问题,正如第三个示例中返回的 12000,而不是 12。## 使用 format() 进行字符串格式化

与数字一样,字符串也可以使用 format() 以类似的方式进行格式化。

示例 6:带填充和对齐的字符串格式化

# 字符串左对齐填充
print("{:5}".format("cat"))

# 字符串右对齐填充
print("{:>5}".format("cat"))

# 字符串居中对齐填充
print("{:^5}".format("cat"))

# 字符串居中对齐填充
# 并使用 '*' 作为填充字符
print("{:*^5}".format("cat"))

输出

cat
cat
cat
*cat*

示例 7:使用 format() 截断字符串

# 将字符串截断为 3 个字母
print("{:.3}".format("caterpillar"))

# 将字符串截断为 3 个字母
# 并进行填充
print("{:5.3}".format("caterpillar"))

# 将字符串截断为 3 个字母,
# 进行填充和居中对齐
print("{:^5.3}".format("caterpillar"))

输出

cat
cat
cat

使用 format() 格式化类和字典成员

Python 在内部使用 getattr() 为类成员以 ".age" 的形式进行格式化。对于字典成员,它使用 __getitem__() 查找以 "[index]" 的形式。

示例 8:使用 format() 格式化类成员

# 定义 Person 类
class Person:
age = 23
name = "Adam"

# 格式化 age
print("{p.name}'s age is: {p.age}".format(p=Person()))

输出

Adam's age is: 23

这里,Person 对象作为关键字参数 p 传递。

在模板字符串中,使用 .name.age 分别访问 Person 的姓名和年龄。

示例 9:使用 format() 格式化字典成员

# 定义 Person 字典
person = {'age': 23, 'name': 'Adam'}

# 格式化 age
print("{p[name]}'s age is: {p[age]}".format(p=person))

输出

Adam's age is: 23

与类似,person 字典作为关键字参数 p 传递。

在模板字符串中,使用 [name][age] 分别访问 person 的姓名和年龄。

使用 Python 的 str.format(**mapping) 更容易地格式化字典。

# 定义 Person 字典
person = {'age': 23, 'name': 'Adam'}

# 格式化 age
print("{name}'s age is: {age}".format(**person))

** 是一个格式参数(最小字段宽度)。

使用 format() 将参数作为格式代码

您还可以将格式代码(如精度、对齐、填充字符)作为位置或关键字参数动态传递。

示例 10:使用 format() 进行动态格式化

# 动态字符串格式模板
string = "{:{fill}{align}{width}}"

# 作为参数传递格式代码
print(string.format('cat', fill='*', align='^', width=5))

# 动态浮点数格式模板
num = "{:{align}{width}.{precision}f}"

# 作为参数传递格式代码
print(num.format(123.236, align='<', width=8, precision=2))

输出

*cat*
123.24

这里,

  • 在第一个示例中,'cat' 是需要格式化的位置参数。同样,fill='*'align='^'width=5 是关键字参数。

  • 在模板字符串中,这些关键字参数不是作为普通字符串进行检索,而是实际的格式代码 fill, align and width

    参数替换相应的命名占位符,并相应地格式化字符串 'cat'。

  • 同样,在第二个示例中,123.236 是位置参数,align、width 和 precision 作为格式代码传递给模板字符串。

使用 format() 的额外格式化选项

format() 还支持特定类型的格式化选项,如 datetime 和复数的格式化。

format() 在内部为 datetime 调用 __format__(),而对于复数,format() 访问其属性。

您可以轻松覆写任何对象的 __format__() 方法以进行自定义格式化。

示例 11:使用 format() 的类型特定格式化和覆写 format() 方法

import datetime
# datetime 格式化
date = datetime.datetime.now()
print("It's now: {:%Y/%m/%d %H:%M:%S}".format(date))

# 复数格式化
complexNumber = 1+2j
print("Real part: {0.real} and Imaginary part: {0.imag}".format(complexNumber))

# 自定义 __format__() 方法
class Person:
def __format__(self, format):
if(format == 'age'):
return '23'
return 'None'

print("Adam's age is: {:age}".format(Person()))

输出

It's now: 2016/12/02 04:16:28
Real part: 1.0 and Imaginary part: 2.0
Adam's age is: 23

这里,

  • 对于 datetime: 当前 datetime 作为位置参数传递给 format() 方法。 并且,内部使用 __format__() 方法,format() 访问年、月、日、小时、分钟和秒。
  • 对于复数: 1+2j 在内部转换为 ComplexNumber 对象。 然后访问其属性 realimag,对数字进行格式化。
  • 覆写 format(): 像 datetime 一样,您可以覆写自己的 __format__() 方法进行自定义格式化,当以 {:age} 访问时返回年龄。

您还可以使用对象的 __str__()__repr__() 功能,并使用 format() 的简写符号 !r!s

__format__() 一样,您可以轻松覆写对象的 __str__()__repr__() 方法。

示例 12:使用 format() 的 str()repr() 简写 !r 和 !s

# __str__() 和 __repr__() 的简写 !r 和 !s
print("引号: {0!r}, 无引号: {0!s}".format("cat"))

# 类的 __str__() 和 __repr__() 实现
class Person:
def __str__(self):
return "STR"
def __repr__(self):
return "REPR"

print("repr: {p!r}, str: {p!s}".format(p=Person()))

输出

引号: 'cat', 无引号: cat
repr: REPR, str: STR