Skip to content

字符串格式化

Python 的字符串格式化有两种方式

  • %格式符方式
  • format 方式

事实上,格式化借助的是对象的魔术方法。
实现了__format__的对象才适用于 format 方式格式化输出,
实现了__str____repr__的对象才分别适用于格式符%s%r输出。
在面向对象章节有给对象定义魔术方法的示例。

%格式符

一般格式为 %(name) + format_spec

[[fill]align][sign][#][0][width][grouping_option][.precision][type]

name

可选,用于选择指定的 key

python
"%(name)s——%(age)d" % {"name": "宝钟玛琳", "age": 17}
# '宝钟玛琳——17'

s 和 d 属于 [type]

format_spec 规则的常用组分:

sign

可选,数字和字符串可供选择的值有:

  • + 右对齐;正数负数前加正负号
  • - 左对齐;负数前加负号
  • 空格 右对齐;负数前加负号
  • 0 右对齐;正数前无符号,负数前加负号;用 0 填充空白处

width

可选,占有宽度

python
"%(name)+7s——%(age)-5d" % {"name": "宝钟玛琳", "age": 17}
# '   宝钟玛琳——17   '

.precision

可选,小数点后保留的位数 默认 6 位

type

类型,必选

任意对象:

  • %s 字符串 (采用str()的显示)

  • %r 字符串 (采用repr()的显示)

  • %c 单个字符

字符串和整数:

  • %b 二进制整数
  • %% 字符"%"转义

数字:

  • %d 十进制整数
  • %i 十进制整数
  • %o 八进制整数
  • %x 十六进制整数
  • %e 指数 (基底写为 e)
  • %E 指数 (基底写为 E)
  • %f 浮点数
  • %F 浮点数,与上相同
  • %g 科学计数法(e)或浮点数 (根据显示长度)
  • %G 科学计数法(E)或浮点数 (根据显示长度)
  • %% 字符"%"
python
"——%(p).2f" % {"p": 0.1 + 0.2}
# '——0.30'
"——%(p).2g" % {"p": 0.1 + 0.2}
# '——0.3'

终端字体颜色

在 win10,输出流需要做**os.system("")**处理才可以输出带颜色的字符

可以使用第三方模块 colorama 来简化语句,它同时使低于 win10 的系统支持转义颜色:

python
from colorama import init, Fore

init(autoreset=False)  # 给True的时候print时无需+Fore.RESET
print(Fore.RED + "helloworld" + Fore.RESET)

内置函数format()

内置函数format(value[, format_spec])
第二个参数即 format_spec 格式规格迷你语言
实现了魔术方法__format__的对象都可以使用

以数字对象的格式化为例:

shell
>>> format(12, '+.3f') # 保留3位小数
'+12.000'
>>> format(3, 'b') # 二进制转化
'11'

其他实现了魔术方法 __format__ 的对象,这里以 datetime.time 对象为例:

shell
>>> from datetime import *
>>> night = time(22,30,tzinfo=timezone(timedelta(hours=8), name = '北京'))
>>> format(night,'现在是%Z时间%H点%M分')
'现在是北京时间22点30分'

datetime模块后续会介绍。

str.format()

与内置函数 format 效果一样,只是变成了 format_spec 去调用字符串方法

涉及到对象方法以及函数的传参方式,将在后面章节介绍。

python
" {}  {}  {} ".format(a, b, c)
" {0}  {1}  {2} ".format(a, b, c)
" {0}  {1}  {2} ".format(*[a, b, c])
" {a}  {b}  {c} ".format(a=a, b=b, c=c)
" {a}  {b}  {c} ".format(**{"a": a, "b": b, "c": c})

{!s}是默认的

python
"{!s}、{!a}、{!r}"  # 分别表示str、ascii和repr方法。

实现了魔术方法__format__的对象可以使用冒号 : format_spec

shell
>>> '0x{:x}'.format(255)
'0xff'

datetime.time对象为例的其他实现了魔术方法__format__的对象:

shell
# 接上节
>>> '现在是{:%Z}时间{:%H}点{:%M}分'.format(night,night,night)
'现在是北京时间22点30分'
>>> '{:现在是%Z时间%H点%M分}'.format(night)
'现在是北京时间22点30分'

转义:{{ ,}} 可以不解析花括号

f 字符串

python3.6+

与内置函数format()以及str.format()一样可以直接使用f 字符串的写法
f'{a}{b}{c}'即可代替'{a}{b}{c}'.format(a=a,b=b,c=c)
f 字符串中不允许使用\转义字符。

%格式符的不同:
Sign 对齐使用<> 而不是 +-^ 用来居中。

shell
>>> '%-6d000'%233
233   000
>>> f'{233:<6d}000'
233   000

datetime.time对象为例的其他实现了魔术方法__format__的对象:

shell
# 接上节
>>> f'现在是{night:%Z}时间{night:%H}点{night:%M}分'
'现在是北京时间22点30分'
>>> f'{night:现在是%Z时间%H点%M分}'
'现在是北京时间22点30分'

python3.8+

f 字符串中可以直接使用说明符=调试,

shell
>>> python = 3.8
>>> f"{python=}"
'python=3.8'

内置函数str()repr()

str()不止是构造函数(class)实例化一个str对象,
str(o)它也是对参数对象进行魔术方法的调用:o.__str__(),将参数转换为了str对象
无论是print(o)f'{o}', "%s"%o,它们都是对魔术方法 o.__str__()的调用


repr(o)f'{o!r}', "%r"%o则是对魔术方法 o.__repr__()的调用,
它会以字面量的形式呈现对象,即字符串带有引号,列表变成'['+ repr(成员) + ',]'
f 字符串f'{o=}'就相当于f'o={repr(o)}'

去除缩进

python
from textwrap import dedent

if __name__ == "__main__":
    code = """
        fun main(){
            println("Hello, world!")
        }
    """
    print(dedent(code))