[重要] Python 格式化说明符
Python 格式化说明符
在 Python 中,格式化说明符是用于控制字符串格式化输出的语法规则。主要有两种方式:旧式 % 格式化 和 新式 f-string/format() 方法。下面是详细介绍:
一、旧式 % 格式化
使用 % 作为占位符,语法:"格式化字符串" % (值1, 值2, ...)
常用说明符:
| 符号 | 作用 | 示例 |
|---|---|---|
%s |
字符串 | '%s岁' % 18 → '18岁' |
%d |
整数 | '%d月' % 3.14 → '3月' |
%f |
浮点数 | '%.2f元' % 3.1415 → '3.14元' |
%x |
十六进制整数 | '%x' % 255 → 'ff' |
%% |
输出百分号 % |
'成功率:%.1f%%' % 90.5 → '成功率:90.5%' |
高级用法:
- 宽度与精度:
%[宽度].[精度]类型'%10s' % 'hello' # 宽度10,右对齐:' hello' '%06d' % 123 # 宽度6,不足补零:'000123' '%.3f' % 3.14159 # 保留3位小数:'3.142'
二、新式 f-string/format() 方法
1. f-string(Python 3.6+)
在字符串前加 f,直接嵌入表达式:f"内容 {表达式:格式化规则}"
2. format() 方法
使用 {} 占位符,通过 .format() 填充值:"内容 {0:格式化规则} {1:规则}".format(值1, 值2)
常用格式化规则:
| 规则 | 示例 | 输出结果 |
|---|---|---|
| 字符串对齐 | ||
:<宽度> |
f'{"hello":<10}' |
'hello '(左对齐) |
:>宽度 |
f'{"hello":>10}' |
' hello'(右对齐) |
:^宽度 |
f'{"hello":^10}' |
' hello '(居中对齐) |
| 数值格式化 | ||
:, |
f'{1234567:,}' |
'1,234,567'(千分位分隔符) |
:+ |
f'{123:+}' |
'+123'(显示正负号) |
:0宽度 |
f'{123:08d}' |
'00000123'(补零) |
| 浮点数精度 | ||
:.2f |
f'{3.14159:.2f}' |
'3.14'(保留2位小数) |
:.1% |
f'{0.123:.1%}' |
'12.3%'(百分比格式) |
| 进制转换 | ||
:b |
f'{255:b}' |
'11111111'(二进制) |
:x |
f'{255:x}' |
'ff'(十六进制) |
:o |
f'{255:o}' |
'377'(八进制) |
三、综合对比
| 场景 | 旧式 % 格式化 | 新式 f-string |
|---|---|---|
| 简单变量替换 | '%s %d' % ('age', 18) |
f'{name} {age}' |
| 复杂表达式 | 不支持直接嵌入 | f'{math.sqrt(2):.2f}' |
| 可读性 | 较差(符号多) | 较好(直观) |
| 性能 | 较慢 | 较快(推荐优先使用) |
示例代码
# f-string 示例
name = "Alice"
age = 25
height = 1.65
print(f"{name} 今年 {age} 岁,身高 {height:.2f} 米")
# 输出:Alice 今年 25 岁,身高 1.65 米
# format() 示例
print("{} 的年薪是 {:.2f} 万元".format("Bob", 18.567))
# 输出:Bob 的年薪是 18.57 万元
# 数值格式化示例
print(f"π ≈ {3.141592653589793:.5f}") # 保留5位小数
print(f"1000000 的科学计数法:{1000000:e}") # 科学计数法
print(f"右对齐宽度10:{42:>10d}") # 右对齐,宽度10
掌握这些规则后,你可以灵活控制输出格式,让数据展示更加美观。
在 Python 中,格式化说明符除了常见用法外,还有许多特殊的高级特性,以下是一些鲜为人知但非常实用的用法:
一、类型特定的格式化
1. 字符串截断
使用 .<宽度> 限制字符串长度(超过部分截断):
text = "Hello, World!"
print(f"{text:.5}") # 输出:Hello
2. 二进制/八进制/十六进制前缀
在进制转换中添加 # 显示前缀(0b, 0o, 0x):
num = 255
print(f"{num:#b}") # 输出:0b11111111
print(f"{num:#x}") # 输出:0xff
3. 科学计数法
使用 e 或 E 控制科学计数法的大小写:
x = 123456789
print(f"{x:.2e}") # 输出:1.23e+08
print(f"{x:.2E}") # 输出:1.23E+08
二、动态格式化参数
1. 从变量获取宽度/精度
用 {} 包裹变量名作为格式化参数:
width = 10
precision = 3
x = 3.14159
print(f"{x:{width}.{precision}f}") # 等价于:{x:10.3f}
# 输出: 3.142
2. 嵌套格式化
在格式化字符串中嵌套表达式:
value = 42
padding = 5
print(f"The answer is {value:0{padding}d}")
# 等价于:{value:05d},输出:The answer is 00042
三、对齐与填充
1. 自定义填充字符
在对齐符号前指定填充字符(默认为空格):
text = "hi"
print(f"{text:*>10}") # 右对齐,用 * 填充左侧
# 输出:********hi
print(f"{text:0^10}") # 居中对齐,用 0 填充两侧
# 输出:0000hi0000
2. 符号对齐
对于负数,控制符号与数字的对齐方式:
num = -123
print(f"{num:<10}") # 符号和数字整体左对齐
# 输出:-123
print(f"{num:<-10}") # 符号左对齐,数字右对齐(罕见用法)
# 输出:- 123
四、特殊数值处理
1. 千位分隔符变体
使用 _ 作为千位分隔符(Python 3.6+):
x = 1000000
print(f"{x:_}") # 输出:1_000_000
2. 复数格式化
直接格式化复数时需分别处理实部和虚部:
z = 3 + 4j
print(f"实部:{z.real:.2f},虚部:{z.imag:.2f}i")
# 输出:实部:3.00,虚部:4.00i
3. NaN 和 Infinity 显示
控制非数字和无穷大的显示格式:
import math
nan = math.nan
inf = math.inf
print(f"{nan:.2f}") # 输出:nan
print(f"{inf:+.2f}") # 输出:+inf
五、格式化自定义对象
为类定义 __format__ 方法,自定义格式化行为:
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __format__(self, format_spec):
if format_spec == "polar":
r = (self.x**2 + self.y**2) ** 0.5
theta = math.atan2(self.y, self.x)
return f"({r:.2f}, {theta:.2f} rad)"
else:
return f"({self.x}, {self.y})"
p = Point(3, 4)
print(f"笛卡尔坐标:{p}") # 默认格式
print(f"极坐标:{p:polar}") # 自定义格式
# 输出:
# 笛卡尔坐标:(3, 4)
# 极坐标:(5.00, 0.93 rad)
六、日期时间格式化
在 datetime 对象中使用 strftime 格式代码:
from datetime import datetime
now = datetime.now()
print(f"{now:%Y-%m-%d %H:%M:%S}") # 标准日期时间
# 输出:2023-06-15 14:30:45
print(f"{now:%A, %B %d, %Y}") # 完整星期和月份
# 输出:Thursday, June 15, 2023
总结
这些特殊用法让 Python 的格式化功能更加灵活强大。例如在数据可视化中,可以用 {x:,} 添加千位分隔符;在嵌入式系统开发中,可用 {x:08b} 生成8位二进制字符串。掌握这些技巧能让你的代码更简洁、输出更规范。
在 Python 的格式化字符串中,类型特定的格式化规则针对不同数据类型有不同的行为。以下是主要数据类型及其支持的特殊格式化特性:
一、字符串(str)
| 格式化规则 | 作用 | 示例 |
|---|---|---|
:.n |
截断字符串至 n 个字符 |
f"{'HelloWorld':.5}" → 'Hello' |
:<宽度> |
左对齐 | f"{'hi':<10}" → 'hi ' |
:>宽度 |
右对齐 | f"{'hi':>10}" → ' hi' |
:^宽度 |
居中对齐 | f"{'hi':^10}" → ' hi ' |
:[填充字符][对齐][宽度] |
自定义填充对齐 | f"{'hi':*<10}" → 'hi********' |
二、整数(int)
| 格式化规则 | 作用 | 示例 |
|---|---|---|
:d |
十进制整数 | f"{42:d}" → '42' |
:b |
二进制 | f"{255:b}" → '11111111' |
:o |
八进制 | f"{255:o}" → '377' |
:x / :X |
十六进制(小写/大写) | f"{255:x}" → 'ff' |
:#b / :#o / :#x |
带前缀的进制 | f"{255:#x}" → '0xff' |
:, |
千位分隔符(用逗号) | f"{1000000:,}" → '1,000,000' |
:_ |
千位分隔符(用下划线) | f"{1000000:_}" → '1_000_000' |
:+ |
始终显示符号 | f"{42:+}" → '+42' |
:0宽度 |
补零 | f"{42:08d}" → '00000042' |
三、浮点数(float)与复数(complex)
| 格式化规则 | 作用 | 示例 |
|---|---|---|
:.nf |
保留 n 位小数 |
f"{3.14159:.2f}" → '3.14' |
:e / :E |
科学计数法(小写/大写) | f"{1000:e}" → '1.000000e+03' |
:g / :G |
自动选择科学计数法或定点数 | f"{1000:g}" → '1000' |
:% |
百分比格式 | f"{0.123:%}" → '12.300000%' |
:.[n]% |
百分比并保留 n 位小数 |
f"{0.123:.1%}" → '12.3%' |
:+, |
带符号的千位分隔符 | f"{1000000:+,}" → '+1,000,000' |
四、布尔值(bool)
布尔值本质上是整数的子类(True=1,False=0),因此支持整数的格式化规则:
print(f"{True:d}") # 输出:1
print(f"{False:b}") # 输出:0
五、日期时间(datetime)
使用 strftime 格式代码(需配合 datetime 对象):
| 格式化规则 | 作用 | 示例 |
|---|---|---|
%Y |
四位数年份 | f"{dt:%Y}" → '2023' |
%m |
两位数月份 | f"{dt:%m}" → '06' |
%d |
两位数日期 | f"{dt:%d}" → '15' |
%H / %I |
24小时制/12小时制 | f"{dt:%H}" → '14' |
%M |
分钟 | f"{dt:%M}" → '30' |
%S |
秒 | f"{dt:%S}" → '45' |
%A / %a |
完整星期/缩写星期 | f"{dt:%A}" → 'Thursday' |
%B / %b |
完整月份/缩写月份 | f"{dt:%B}" → 'June' |
六、自定义对象
通过实现 __format__ 方法支持任意格式:
class Money:
def __init__(self, amount):
self.amount = amount
def __format__(self, spec):
if spec == 'CNY':
return f"¥{self.amount:.2f}"
else:
return str(self.amount)
m = Money(123.456)
print(f"{m:CNY}") # 输出:¥123.46
总结
| 数据类型 | 核心支持的格式化规则 |
|---|---|
| 字符串(str) | 截断、对齐、填充 |
| 整数(int) | 进制转换、千位分隔符、符号控制 |
| 浮点数(float) | 精度控制、科学计数法、百分比 |
| 日期时间(datetime) | 年月日时分秒格式化 |
| 自定义对象 | 通过 __format__ 方法自定义任何格式 |
理解这些特性后,你可以针对不同类型的数据,灵活运用格式化规则来满足各种输出需求。
除了字符串和整数外,以下数据类型也支持类型特定的格式化规则:
一、浮点数(float)
浮点数支持多种数值格式化选项,常用于控制精度、显示方式和对齐:
1. 精度控制
x = 3.1415926
print(f"{x:.2f}") # 保留2位小数:3.14
print(f"{x:.5f}") # 保留5位小数:3.14159
2. 科学计数法
print(f"{x:e}") # 小写e:3.141593e+00
print(f"{x:E}") # 大写E:3.141593E+00
print(f"{1000000:g}") # 自动选择格式:1e+06
3. 百分比格式
rate = 0.1234
print(f"{rate:%}") # 百分比:12.340000%
print(f"{rate:.1%}") # 保留1位小数:12.3%
4. 千位分隔符与符号
large_num = 1234567.89
print(f"{large_num:,}") # 千位分隔符:1,234,567.89
print(f"{large_num:+}") # 显示符号:+1234567.89
print(f"{large_num:015.2f}") # 补零到15位宽度:0001234567.89
二、复数(complex)
复数需分别格式化实部和虚部:
z = 3 + 4j
print(f"实部:{z.real:.2f},虚部:{z.imag:.2f}i")
# 输出:实部:3.00,虚部:4.00i
三、布尔值(bool)
布尔值作为整数的子类,支持整数的格式化规则:
print(f"{True:d}") # 作为整数:1
print(f"{False:b}") # 作为二进制:0
四、日期时间(datetime)
使用 strftime 格式代码(需配合 datetime 对象):
from datetime import datetime
now = datetime.now()
print(f"{now:%Y-%m-%d}") # 日期:2023-06-15
print(f"{now:%H:%M:%S}") # 时间:14:30:45
print(f"{now:%A, %B %d, %Y}") # 完整格式:Thursday, June 15, 2023
常用日期时间格式代码:
| 代码 | 含义 | 示例 |
|---|---|---|
%Y |
四位数年份 | 2023 |
%m |
两位数月份 | 06 |
%d |
两位数日期 | 15 |
%H |
24小时制小时 | 14 |
%I |
12小时制小时 | 02 |
%M |
分钟 | 30 |
%S |
秒 | 45 |
%A |
完整星期名 | Thursday |
%a |
缩写星期名 | Thu |
%B |
完整月份名 | June |
%b |
缩写月份名 | Jun |
五、自定义对象
通过实现 __format__ 方法支持任意格式:
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __format__(self, spec):
if spec == "polar":
r = (self.x**2 + self.y**2) ** 0.5
theta = math.atan2(self.y, self.x)
return f"({r:.2f}, {theta:.2f} rad)"
else:
return f"({self.x}, {self.y})"
p = Point(3, 4)
print(f"笛卡尔坐标:{p}") # 默认格式:(3, 4)
print(f"极坐标:{p:polar}") # 自定义格式:(5.00, 0.93 rad)
六、字典(dict)与列表(list)
虽然没有内置的特殊格式化规则,但可以通过嵌套表达式实现复杂格式:
data = {"name": "Alice", "age": 25}
print(f"姓名:{data['name']},年龄:{data['age']}")
# 输出:姓名:Alice,年龄:25
nums = [1, 2, 3, 4]
print(f"列表:[{', '.join(f'{n:02d}' for n in nums)}]")
# 输出:列表:[01, 02, 03, 04]
总结
| 数据类型 | 核心格式化特性 | 示例 |
|---|---|---|
| 浮点数(float) | 精度控制、科学计数法、百分比 | f"{3.1415:.2f}" → '3.14' |
| 复数(complex) | 分别格式化实部和虚部 | f"{z.real:.2f} + {z.imag:.2f}i" |
| 布尔值(bool) | 作为整数格式化 | f"{True:d}" → '1' |
| 日期时间(datetime) | 年月日时分秒格式化 | f"{dt:%Y-%m-%d}" → '2023-06-15' |
| 自定义对象 | 通过 __format__ 方法自定义格式 |
f"{obj:custom_format}" |
掌握这些类型特定的格式化规则后,可以更灵活地处理各种数据类型的输出需求。

浙公网安备 33010602011771号