如果你已经掌握了 Python 字符串格式化的基本用法(比如 f"Hello {name}" 或 "{}".format(age)),那么恭喜你,你已经能够处理大部分日常输出需求。但当你需要输出对齐的表格、带千位分隔符的大数字、百分比、进制转换,甚至自定义对象的格式化时,基础用法就显得不够了。
本文将带你深入探索 Python 字符串格式化的进阶技巧,包括:
format() 方法的深层用法% 格式化的一些高级特性学完本文,你的输出将更加专业、灵活。
f-string(格式化字符串字面量)自 Python 3.6 引入,因其简洁、直观、高效而成为首选。但很多人只用了它的冰山一角。
使用 :<、:>、:^ 可以分别实现左对齐、右对齐、居中,并指定宽度。
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**'小数位数
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'(正数前加空格)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}") # 0xffdatetime 对象支持与 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日 Thursdayf-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'未成年'}") # 未成年user = {"name": "张三", "age": 25}
print(f"姓名:{user['name']},年龄:{user['age']}")
points = [(10, 20), (30, 40)]
print(f"第一个点:{points[0][0]}, {points[0][1]}")用三引号可以创建多行 f-string,但注意每行前都要加 f(Python 3.12+ 允许跨行直接写,但建议显式标记)。
name = "小明"
age = 18
info = f"""
姓名:{name}
年龄:{age}
职业:学生
"""
print(info)如果需要输出花括号本身,用双花括号 {{ 和 }} 转义。
print(f"{{ 这是花括号 }}") # { 这是花括号 }f-string 在运行时计算,速度通常比 format() 和 % 格式化更快,因为它是编译时的语法糖。
str.format() 是一个更早引入的格式化方法,虽然不如 f-string 直观,但在某些场景(如需要延迟格式化、格式化字符串模板来自外部)仍然有用。
print("{0} {1} {0}".format("hello", "world")) # hello world helloprint("{name} 今年 {age} 岁".format(name="李四", age=22))语法:{[[填充]对齐][符号][#][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%print("{:b}".format(255)) # 11111111
print("{:#x}".format(255)) # 0xffformat() 不能直接格式化 datetime 对象,但可以通过自定义类或使用 __format__ 方法,更常用的是结合 strftime 或 f-string。
__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__ 被调用)虽然不推荐在新代码中使用,但维护老代码时仍会遇到。
data = {'name': '张三', 'age': 25}
print("%(name)s 今年 %(age)d 岁" % data) # 张三 今年 25 岁print("%10s" % "Python") # ' Python'
print("%.2f" % 3.14159) # 3.14
print("%+05d" % 42) # +0042print("%x" % 255) # ff
print("%o" % 255) # 377data = [
("小明", 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.5amount = 1234567.89
print(f"¥{amount:,.2f}") # ¥1,234,567.89from datetime import datetime
log_msg = f"[{datetime.now():%Y-%m-%d %H:%M:%S}] 用户登录成功"
print(log_msg)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)num = 0b10101110
print(f"二进制:{num:08b}") # 10101110(补零到8位)
print(f"十六进制:{num:#04x}") # 0xaename = "张三"
address = "北京市朝阳区某某街道123号"
phone = "13800138000"
card = f"""
┌────────────────────────────┐
│ 姓名:{name:<20}│
│ 地址:{address:<20}│
│ 电话:{phone:<20}│
└────────────────────────────┘
"""
print(card)format() | % | ||
Python 提供了极其强大的字符串格式化能力,掌握进阶技巧后,你可以:
format()。% 格式化。最重要的建议:尽量使用 f-string,它是最现代、最易读的方式。结合本文介绍的对齐、填充、数字格式化、日期时间、进制转换等功能,你的输出将变得更加专业和美观。
希望本文能帮助你写出更优雅的 Python 代码。