当前位置:首页>python>Python字符串格式化进阶——让你的输出更专业

Python字符串格式化进阶——让你的输出更专业

  • 2026-09-04 03:23:10
Python字符串格式化进阶——让你的输出更专业

一、引言

如果你已经掌握了 Python 字符串格式化的基本用法(比如 f"Hello {name}" 或 "{}".format(age)),那么恭喜你,你已经能够处理大部分日常输出需求。但当你需要输出对齐的表格、带千位分隔符的大数字、百分比、进制转换,甚至自定义对象的格式化时,基础用法就显得不够了。

本文将带你深入探索 Python 字符串格式化的进阶技巧,包括:

  • • f-string 的完整功能
  • • format() 方法的深层用法
  • • 旧式 % 格式化的一些高级特性
  • • 实用案例:表格、金额、进度条、进制转换等

学完本文,你的输出将更加专业、灵活。


二、f-string 进阶

f-string(格式化字符串字面量)自 Python 3.6 引入,因其简洁、直观、高效而成为首选。但很多人只用了它的冰山一角。

2.1 对齐与填充

使用 :<、:>、:^ 可以分别实现左对齐、右对齐、居中,并指定宽度。

name = "Python"
print(f"{name:<10}")   # 'Python    '
print(f"{name:>10}")   # '    Python'
print(f"{name:^10}")   # '  Python  '

可以在对齐符号前指定填充字符(默认为空格)。

print(f"{name:*<10}")  # 'Python****'
print(f"{name:*>10}")  # '****Python'
print(f"{name:*^10}")  # '**Python**'

2.2 数字格式化

小数位数

pi = 3.1415926
print(f"{pi:.2f}")     # 3.14
print(f"{pi:.3f}")     # 3.142

千位分隔符

big_num = 1234567890
print(f"{big_num:,}")   # 1,234,567,890
print(f"{big_num:_}")   # 1_234_567_890(Python 3.6+)

百分比

rate = 0.856
print(f"{rate:.1%}")    # 85.6%
print(f"{rate:.2%}")    # 85.60%

科学计数法

print(f"{big_num:.2e}") # 1.23e+09

符号显示

positive = 42
negative = -42
print(f"{positive:+}")  # +42
print(f"{negative:+}")  # -42
print(f"{positive: }")  # ' 42'(正数前加空格)

2.3 进制转换

num = 255
print(f"{num:b}")   # 11111111(二进制)
print(f"{num:o}")   # 377(八进制)
print(f"{num:x}")   # ff(十六进制小写)
print(f"{num:X}")   # FF(十六进制大写)
print(f"{num:
#b}")  # 0b11111111(带前缀)
print(f"{num:#o}")  # 0o377
print(f"{num:#x}")  # 0xff

2.4 日期时间格式化

datetime 对象支持与 strftime 相同的格式化代码。

from datetime import datetime
now = datetime.now()
print(f"{now:%Y-%m-%d %H:%M:%S}")       # 2025-03-20 14:30:00
print(f"{now:%Y年%m月%d日 %A}")         # 2025年03月20日 Thursday

2.5 表达式和函数调用

f-string 的花括号里可以放任何有效的 Python 表达式,包括运算、方法调用、甚至三元表达式。

name = "alice"
print(f"{name.upper()}")        # ALICE
print(f"{len(name)}")           # 5

scores = [85, 92, 78]
print(f"平均分:{sum(scores)/len(scores):.1f}")  # 平均分:85.0

age = 17
print(f"{'成年'if age >= 18else'未成年'}")   # 未成年

2.6 访问字典、列表元素

user = {"name": "张三", "age": 25}
print(f"姓名:{user['name']},年龄:{user['age']}")

points = [(10, 20), (30, 40)]
print(f"第一个点:{points[0][0]}, {points[0][1]}")

2.7 多行 f-string

用三引号可以创建多行 f-string,但注意每行前都要加 f(Python 3.12+ 允许跨行直接写,但建议显式标记)。

name = "小明"
age = 18
info = f"""
姓名:{name}
年龄:{age}
职业:学生
"""

print(info)

2.8 大括号转义

如果需要输出花括号本身,用双花括号 {{ 和 }} 转义。

print(f"{{ 这是花括号 }}")   # { 这是花括号 }

2.9 性能

f-string 在运行时计算,速度通常比 format() 和 % 格式化更快,因为它是编译时的语法糖。


三、format() 方法进阶

str.format() 是一个更早引入的格式化方法,虽然不如 f-string 直观,但在某些场景(如需要延迟格式化、格式化字符串模板来自外部)仍然有用。

3.1 位置参数与索引

print("{0} {1} {0}".format("hello", "world"))  # hello world hello

3.2 关键字参数

print("{name} 今年 {age} 岁".format(name="李四", age=22))

3.3 格式说明符

语法:{[[填充]对齐][符号][#][0][宽度][,][.精度][类型]}

  • • 填充与对齐:与 f-string 相同,<、>、^ 前可加填充字符。
  • • 符号:+ 显示正负号,- 仅负数显示(默认),空格表示正数留空。
  • • #:用于进制前缀(0b、0o、0x)。
  • • 0:用零填充宽度。
  • • 宽度:最小宽度。
  • • ,:千位分隔符。
  • • .精度:小数位数。
  • • 类型:d(整数)、f(浮点)、%(百分比)、e(科学计数)、b/o/x/X(进制)等。
print("{:+05d}".format(42))       # +0042
print("{:#010b}".format(255))     # 0b11111111(宽度10,不足补空格?实际#占用两位,需调整)
# 更准确的示例:
print("{:+#010b}".format(255))    # +0b11111111(宽度10,但前缀占3位)

千位分隔符

print("{:,}".format(1234567))     # 1,234,567

百分比

print("{:.2%}".format(0.856))     # 85.60%

3.4 进制转换

print("{:b}".format(255))         # 11111111
print("{:#x}".format(255))        # 0xff

3.5 日期时间格式化

format() 不能直接格式化 datetime 对象,但可以通过自定义类或使用 __format__ 方法,更常用的是结合 strftime 或 f-string。

3.6 自定义类支持 __format__

如果你的类实现了 __format__ 方法,就可以在格式化时被调用。

classMoney:
def__init__(self, amount):
self.amount = amount
def__format__(self, spec):
if spec == 'cny':
returnf"¥{self.amount:.2f}"
returnstr(self.amount)

m = Money(19.99)
print(f"{m:cny}")     # ¥19.99(需要 Python 3.6+,但这里演示 __format__ 被调用)

四、% 格式化(旧式)的补充

虽然不推荐在新代码中使用,但维护老代码时仍会遇到。

4.1 字典映射

data = {'name': '张三', 'age': 25}
print("%(name)s 今年 %(age)d 岁" % data)   # 张三 今年 25 岁

4.2 宽度与精度

print("%10s" % "Python")      # '    Python'
print("%.2f" % 3.14159)       # 3.14
print("%+05d" % 42)           # +0042

4.3 进制转换

print("%x" % 255)   # ff
print("%o" % 255)   # 377

五、实战案例

案例1:生成对齐的表格

data = [
    ("小明", 18, 85.5),
    ("李小红", 19, 92.0),
    ("王五", 18, 78.5),
]

# 表头
print(f"{'姓名':<10}{'年龄':<6}{'分数':>6}")
print("-" * 22)
for name, age, score in data:
print(f"{name:<10}{age:<6}{score:>6.1f}")

输出:

姓名        年龄      分数
-----------------------
小明        18       85.5
李小红      19       92.0
王五        18       78.5

案例2:格式化金额(带千位分隔符)

amount = 1234567.89
print(f"¥{amount:,.2f}")   # ¥1,234,567.89

案例3:日志时间戳

from datetime import datetime
log_msg = f"[{datetime.now():%Y-%m-%d %H:%M:%S}] 用户登录成功"
print(log_msg)

案例4:进度条模拟

defprogress_bar(current, total, bar_length=20):
    percent = current / total
    filled = int(bar_length * percent)
    bar = '█' * filled + '░' * (bar_length - filled)
print(f"\r进度:|{bar}| {percent:>6.1%}", end='')
if current == total:
print()

import time
for i inrange(101):
    progress_bar(i, 100)
    time.sleep(0.02)

案例5:二进制查看器

num = 0b10101110
print(f"二进制:{num:08b}")   # 10101110(补零到8位)
print(f"十六进制:{num:#04x}") # 0xae

案例6:格式化多行输出(地址卡)

name = "张三"
address = "北京市朝阳区某某街道123号"
phone = "13800138000"

card = f"""
┌────────────────────────────┐
│  姓名:{name:<20}│
│  地址:{address:<20}│
│  电话:{phone:<20}│
└────────────────────────────┘
"""

print(card)

六、三种格式化方式对比

特性
f-string
format()%
 格式化
引入版本
3.6+
2.6+
从开始
可读性
⭐⭐⭐⭐⭐
⭐⭐⭐
⭐⭐
性能
快
中等
慢
延迟求值
不支持
支持(模板字符串)
支持
复杂表达式
直接写
间接传参
不方便
推荐度
首选
特定场景
不推荐

七、总结

Python 提供了极其强大的字符串格式化能力,掌握进阶技巧后,你可以:

  • • 用 f-string 写出简洁且强大的格式化代码。
  • • 在需要模板分离时使用 format()。
  • • 维护旧代码时看懂 % 格式化。

最重要的建议:尽量使用 f-string,它是最现代、最易读的方式。结合本文介绍的对齐、填充、数字格式化、日期时间、进制转换等功能,你的输出将变得更加专业和美观。

希望本文能帮助你写出更优雅的 Python 代码。

最新文章

随机文章