Python字符串格式化与F-String语法

字符串格式化

Python的内置方法和标准库所支持的字符串格式化方法一共有以下4种:

  • % 操作符
  • format 内置函数
  • f-string 语法
  • Template 标准库

方式一:% 操作符

其格式说明符和 C 语言常用的格式化方法一致。

"""
%[sign][width][.precision][long][type]
"""
标志 描述 备注
sign 对齐标志 + 结果右对齐,输出符号(正号或负号, 符号占一个宽度单位)
- 结果左对齐,右边填空格,正号不输出,输出负号
(空格)结果右对齐,左边填空格,正号不输出,输出负号
width 输出内容的最小宽度,如果内容不够,填充空格
.precision 显示精度(针对浮点型)
long 长度格式 h 短整型
l 长整型
type 格式化后的目标值显示类型 %c 单个字符
%d 十进制有符号整数
%u 十进制无符号整数
%e 科学计数法, 使用小写"e"
%E 科学计数法, 使用大写"E"
%f 浮点数
%g 使用%e或%f中较短的一个
%G 使用%E或%f中较短的一个
%i 带符号整数,同 %d
%o 无符号以八进制表示的整数
%s 字符串
%x 无符号的十六进制表示的正数,字母以小写 abcdef 表示
%X 无符号的十六进制表示的正数,字母以大写 ABCDEF 表示
%% 一个'%'符号

按位置依次对应

参数需要和格式化的顺序、位置一一对应

# 格式化示例
>>> "%s" % 22
'22'

# 浮点数示例
>>> "%5.2f" % 22.245
'22.25'

# 右对齐显示符号
>>> "%+5d" % 22
'  +22'
>>> "%+5d" % -22
'  -22'

# 拼接
>>> "%d个%s" % (22, "鸡蛋")
'22个鸡蛋'

>>> k = 'name'
>>> v = 'Jack'
>>> "%s = %s" % (k, v)
'name = Jack'

按名称索引

通过字典方式格式化,打破了位置带来的限制与困扰

>>> k = 'name'
>>> v = 'Jack'
>>> "%(key)s = %(value)s" % {'key': k, 'value': v}
'name = Jack'

相信很多熟悉C语言的朋友能很快了解这一点的使用,但是这个已经是Python中不提倡的用法了,因此本文不过多介绍!


方式二:format 内置函数

格式说明符如下:

format(value, 'specifier') -> str
str(value).format('specifier') -> str
"""
specifier 格式如下:
[[fill]align][sign][#][0][width][,|_][.precision][type]
"""

格式描述符标志:

标志 描述 备注
fill 填充字符,默认填充为空格
align 对齐标志 < 左对齐(默认)
> 右对齐
^ 居中对齐
= 强制将填充内容放置在符号(如果有)之后但位于数字之前, 仅适用于数字参数
sign 符号标志 + 负数前加负号,正数前加正号
- 负数前加负号,正数前不加任何符号(默认)
(空格)负数前加负号,正数前加一个空格
# 可选标志:# 选项,适用于数字参数,同时仅适用于目标格式为 2, 8, 16 进制的数字,会在输出的数字前添加 0b, 0o, 0x 前缀 #b 二进制
#o 八进制
#x 十六进制
0 可选标志:0 选项,如果未给出明确的对齐方式, 可以在宽度字段前加上一个 0 字符。 这相当于填充字符 0, 对齐方式为 =
width 最终展示的长度,如果内容不够,默认填充空格,或者由 fill 指定
, or _ 数字间隔符
.precision 显示精度 - 对于由 f/e 或 F/E 格式化的浮点数,该选项指定小数点后的位数
- 对于有 g 或 G 格式化的浮点数,表示小数点前后 一共 多少位
- 对于非整数类型的参数,该选项指定字段最大宽度
type 格式化后的目标值显示类型

目标值显示类型(type标志):

类型 输出描述
d 整型的十进制
b 整型的二进制
o 整型的八进制
x 整型的十六进制(字母小写表示)
X 整型的十六进制(字母大写表示)
f, F 浮点型表示
e 科学计数法: [-]m.dddddde±xx,默认精度为 6
E 科学计数法: [-]m.ddddddE±xx
g, G 一般形式, 受 precision 选项影响
n 入参为整数时,类似 d, 会使用当前区域设置插入适当的数字分隔符
入参为浮点数时,和 g 相同, 会使用当前区域设置插入适当的数字分隔符
% 百分比展示,入参乘100,追加百分号,默认精度为6
s 字符串或任何其他类型的对象,调用对象的 __str__() 方法
c 单个字符,在输出前将整数转化成对应的 unicode 字符

按位置依次对应

a = 3.141592654
d = {'a': a}
>>> "{:0<6.2f}   {:0<7.3f}".format(a, a)
'3.1400   3.14200'

按名称索引

>>> "{val:0<6.2f}   {val:0<7.3f}".format(val=a)
'3.1400   3.14200'

>>> "{val[a]:0<6.2f}   {val[a]:0<7.3f}".format(val=d)
'3.1400   3.14200'

>>> class Values:
...     a = 3.141592654
... 
>>> "{val.a:0<6.2f}   {val.a:0<7.3f}".format(val=Values)
'3.1400   3.14200'

按参数下标索引

>>> "{0:0<6.2f}   {0:0<7.3f}".format(a)
'3.1400   3.14200'

>>> "{0[a]:0<6.2f}   {0[a]:0<7.3f}".format(d)
'3.1400   3.14200'

方式三:f-string语法

f-string语法是Python3.6推出的,是当前备受推荐的字符串格式化方法,该部分我们放到本文的第二大部分讲。


方式四:Template 标准库

>>> from string import Template
"""
Template('format string').substitute(**kwargs) -> str
"""

>>> name='Jack'
>>> t = Template('Hello $name!')
>>> res=t.substitute(name=name)
>>> res
'Hello Jack!'

>>> d = {"name": "Jack", "custom": "What's your job?"}
>>> s = "Hello $name. $custom"
>>> Template(s).substitute(**d)
"Hello Jack. What's your job?"




F-String, 处理字符串的瑞士军刀

在Python3.6中加入,叫做 插值格式字符串(interpolated format string,简称f-string),其用法就是在python原始字符串的基础上增加 f/F 前缀,以大括号 {} 标明被替换的字段。f-string在本质上并不是字符串常量,而是一个在运行时运算求值的表达式。

首先明确基本语法:

f"{value[:specifier]}" -> str	# f大小写都可以
"""
f-string 允许将 Python语句 直接嵌入到目标语句中,使用花括号包裹
同时还可以指定该变量的格式说明符,specifier格式参照上节提到的format中的specifier格式
"""

f-string 使用和 format 规则一样的格式说明符 !!!

简单示例:

>>> name = 'jack'
>>> country = 'china'

>>> f"Hello, I'm {name}, I come from {country}."
"Hello, I'm jack, I come from china."

>>> f"Hello, I'm {name.capitalize()}, I come from {country.capitalize()}."
"Hello, I'm Jack, I come from China."

需要注意:

>>> # 在f-Strings中的使用
>>> f'{obj}'   	# 默认!s, 触发__str__
>>> f'{obj!r}'	# 指定!r, 触发__repr__

变量插入

改变以往占位符或加号拼接的方式,使得字符串拼接更加简单直观,可读性也更好。

>>> name = 'jack'
>>> country = 'china'

>>> f"Hello, I'm {name}, I come from {country}."
"Hello, I'm jack, I come from china."

表达式求值

# 惯性做法, 不推荐
>>> f"2 + 3 = {2 + 3}"
'2 + 3 = 5'

# 新方法
>>> f"{2 + 3 = }"
'2 + 3 = 5'

>>> a, b = 2, 3
>>> f"{a + b = }"
'a + b = 5'

>>> from datetime import datetime
>>> day = datetime(2012, 12, 12)
>>> str(day)
'2012-12-12 00:00:00'
>>> repr(day)
'datetime.datetime(2012, 12, 12, 0, 0)'
>>> f"{day = }"
'day = datetime.datetime(2012, 12, 12, 0, 0)'

可以看出,= 号前的表达式会自动求结果值,并调用结果值的 repr 形式值作为 = 号后的内容


调用函数

>>> name = 'jack'
>>> country = 'china'
>>> f"Hello, I'm {name.capitalize()}, I come from {country.capitalize()}."
"Hello, I'm Jack, I come from China."

使用lambda表达式:

>>> f"result is {(lambda x: x**2+1)(5)}"
'result is 26'

>>> f"{(lambda x: x**2+1)(5) = }"
'(lambda x: x**2+1)(5) = 26'

多行string

name, job = "tom", "student"

s = f"""I'm {name.capitalize()}, 
and I'm a {job.capitalize()}"""

print(s)
"""
I'm Tom, 
and I'm a Student
"""

使用格式说明符

格式说明符即 specifier ,f-string 和 format 的格式说明符遵循一致的规则!

输出内容对齐 & 补全

word = "python"

>>> f"|{word:<10}|"
'|python    |'

>>> f"|{word:>10}|"
'|    python|'

>>> f"|{word:^10}|"
'|  python  |'

带有补全的对齐效果:

# 本例用小数点来补全空余内容
>>> f"|{word:.<10}|"
'|python....|'

>>> f"|{word:.>10}|"
'|....python|'

>>> f"|{word:.^10}|"
'|..python..|'

例子:

格式化一个日期,要求月份、天数用两位表示,不足两位补0

year, month, day = 2022, 1, 1

>>> f"{year}-{month:0>2}-{day:0>2}"
'2022-01-01'

数字格式化

浮点数 :指定精度显示

pi = 3.141592654
print(f"PI = {pi:.2f}")
# PI = 3.14

print(f"PI = {pi:.3f}")
# PI = 3.142

科学计数

print(f"{pi:e}")	# 不指定精度,默认6位小数,和format一致
# 3.141593e+00

print(f"{pi:.2e}")
# 3.14e+00

百分比格式化 :兼顾小数位保留和百分号格式化功能

print(f"PI = {pi:.3%}")
# PI = 314.159%

print(f"PI = {pi:.2%}")
# PI = 314.16%

千位分隔符 :使用 , 格式化数字展示(常用于金额),易于阅读

>>> f"{234234234:,}"
'234,234,234'

>>> f"{234234234.1314:,.2f}"
'234,234,234.13'

>>> f"{234234234.1314:_.2f}"
'234_234_234.13'

进制转换

先看看python中常用的用法及其效果:

num = 23
bin(num)	# '0b10111'
oct(num)	# '0o27'
hex(num)	# '0x17'

在f-string中,b、o、x分别代表二进制、八进制、十六进制

f"{num:b}"	# '10111'
f"{num:o}"	# '27'
f"{num:x}"	# '17'

要想实现常用用法的效果,进制规则代码前需要加#号:

f"{num:#b}"	# '0b10111'
f"{num:#o}"	# '0o27'
f"{num:#x}"	# '0x17'
f"{num:#X}" # '0X17'

日期格式化

适用于 datedatetimetime 对象

today = datetime.datetime.today()
f"{today:%Y}"			# '2022'
f"{today:%Y-%m}"		# '2022-12'
f"{today:%Y-%m-%d}"		# '2022-12-16'

f"{today:%F}"			# '2022-12-16'
f"{today:%D}"			# '12/16/22'
f"{today:%X}"			# '21:01:27'
f"{today:%F %X}"		# '2022-12-16 21:01:27'

更多日期格式信息:日期格式信息


Suggestion

(这个建议是引用的其他地方的,发现很多博文都有,就不标出来源了,因为不确定最初的版本来自哪里)

1、如果格式化的字符串是由用户输入的,那么基于安全性考虑,推荐使用Template

2、如果使用的python3.6+版本的解释器,推荐使用F-Strings

3、如果要兼容python2.x版本的python解释器,推荐使用format形式

4、一般不推荐使用%,尤其是生产环境


posted @ 2022-12-17 17:18  orson奥森  阅读(810)  评论(0编辑  收藏  举报