python 的format 用法

󰃭 2017-09-10

格式化输出

我们需要把字符或数字按照某种格式输出的过程, 就是格式化输出, 在python中, 一般有几种方式

  1. 直接的字符串拼接, 如 'My Name is '+ name
  2. 使用% 占位符, 如 'My Name is %s' %(name,)
  3. 使用format方法, 如'My Name is {}'.format(name)

以上几种方式, 官方推荐的是第三种, 使用format 函数, 相较于1,2 两种方式, format 格式化输出时, 功能更强大, 输出更方便

一下介绍下其常用使用方式

通过位置格式化填充字符

比如上面的例子中, 我们在字符串中保留了{} 作为占位符, format的第一个参数会填充该占位符内容

name = 'Tony'
print('My Name is {}'.format(name)) # My Name is Tony

如果是有多个变量呢

当有多个{} 作为占位符时, 在format中会依次使用相同位置的变量替换该占位符的内容, 如下

name = 'Tony'
age = 18
print('My Name is {}, Age is {}'.format(name, age)) # My Name is Tony, , Age is 18

通过偏移标记填充字符

在使用format 时, 我们还可以通过在占位符中标记偏移量来填充字符串, 格式化输出, 如下

name = 'Tony'
age = 18
print('My Name is {0}, Age is {1}'.format(name, age)) # My Name is Tony, , Age is 18

这种方式里, format会用相应偏移的变量替换相同偏移标记的占位符

可能有人会说这种方式和上一种不是一样的吗, 看下面这种场景:

print('My Name is {0}, Age is {1}, And Your Age is {1}'.format(name, age))
# My Name is Tony, Age is 18, And Your Age is 18

在这种场景下, 我们仅需要在format 中填写更少的变量, 就能替换字符串中所有的占位符, 而如果是上面的方式, 在字符串中有几个{}, 在format中就得写几个变量

而且, 相对于上一中方式, 这种指明偏移的填充方式, 可读性更好些

通过key名填充字符

既然可以通过偏移标记填充字符, 那是不是可以直接通过key来作为填充标记呢

可以, 如下

print('My Name is {name}, Age is {age}'.format(name=name, age=age))
# My Name is Tony, Age is 18

很明显, 相较于通过偏移标记填充字符, 这种方式的可读性会更强

同样, 可以通过更少的format标记, 填充更多字符内容, 只要是key在format中作为关键字参数标记了

如果关键字较多, 还可以通过字典的方式作为format的参数传递, 填充字符串中相应的key的占位符

如下

params = {'name': name, 'age': age}
print('My Name is {name}, Age is {age}'.format(**params))
# My Name is Tony, Age is 18

实际上应用的是python可以将字典解析为函数的关键字参数的传递的特性

同理, 在 通过偏移标记填充字符 部分, 我们也可以利用python 将tuple 作为可变参数传递特性来试一下

params = ('Tony', 18)
print('My Name is {0}, Age is {1}, And Your Age is {1}'.format(*params))
# My Name is Tony, Age is 18, And Your Age is 18

也可以, 哈哈

字符对齐

使用format, 我们可以方便的实现左对齐, 右对齐以及中间对齐, 如下

左对齐

print('{:>10}, {:>10}'.format('tony', 18))
#       tony,         18

还可以标记填充的字符

print('{:=>10}, {:=>10}'.format('tony', 18))
# ======tony, ========18

注意, 对齐的时候的长度是包含了要填充的字符的, 比如tony 部分的左对齐, 实际上是6个= + 4个字母(tony)

下面的例子可能更直观

print("{:=>10}, {:=>10},\n{:=>10}, {:=>10}".format('tony', 18, 'wang', 12344))
# ======tony, ========18,
# ======wang, =====12344

输出的内容是总长度对齐的, 不足长度的部分使用字符填充, 这里是=

右对齐

右对齐和左对齐除了> 变成了 <, 其他行为一致, 如下

print("{:=<10}, {:=<10},\n{:=<10}, {:=<10}".format('tony', 18, 'wang', 12344))
# tony======, 18========,
# wang======, 12344=====

居中对齐

居中对齐是把> 变成了 ^, 其他行为一致

print("{:=^10}, {:=^10},\n{:=^10}, {:=^10}".format('tony', 18, 'wang', 12344))
# ===tony===, ====18====,
# ===wang===, ==12344===

与字符填充结合起来, 如果是使用下标(位置标记的方式), 在: 前面写明下标即可, 如下

print("{0:=^10}, {1:=^10},\n{2:=^10}, {3:=^10}".format('tony', 18, 'wang', 12344))

关键字参数同理

数字格式化

使用format 格式化输出数字时, 常用的场景如下

进制转换

x = 18
print('{:b}'.format(x)) # 十进制 ==> 二进制: 10010

print('{:o}'.format(x)) # 十进制 ==> 八进制: 22

print('{:x}'.format(x)) # 十进制 ==> 十六进制: 12

浮点数精度控制

pi = 3.1415926

print('{:.2f}'.format(pi)) # 保留两位小数: 3.14

转义

在format 中, 我们使用{} 作为占位符, 那如果我希望在输出中, 真的保留{}, 或者保留{}

如果真的希望这样的话, 我们需要使用{} 再去转义 {}, 或者{ 再去转义 {, }再去转义}

如下

print('{{{0:.2f}}}'.format(pi))  # {3.14}

三层 ‘{}’, 第一层{}作为转义标记, 转义第二层{}, 第三层(最里面)作为占位符使用, 替换pi

如果仅是左侧的需要转义呢, 像{3.14 这样的:

print('{{{0:.2f}'.format(pi)) # {3.14

同理

print('{0:.2f}}}'.format(pi)) # 3.14}