答案是使用 f-string 进行字符串格式化。文章介绍了 Python 中三种字符串格式化方法:f-string(推荐,简洁高效,支持表达式和调试)、str.format()(灵活,适用于动态模板和向后兼容)和 % 运算符(过时,可读性差,不推荐新项目使用),并详细说明了各自语法、适用场景及迁移策略。

在 Python 中,想要优雅地格式化字符串,现代且推荐的做法无疑是使用 f-string。它将简洁、可读性和强大的功能集于一身,让代码看起来更自然。当然,
str.format()
%
字符串格式化,本质上就是将变量的值嵌入到预设的字符串模板中。在 Python 里,我们有三种主要的方式来完成这项任务,每种都有其设计哲学和适用场景。
f-string (Formatted String Literals) 这是 Python 3.6 及以后版本引入的,也是我个人最常使用的。它的语法非常直观,你只需要在字符串前加上一个
f
f
{}name = "Alice"
age = 30
city = "New York"
temperature = 25.5
# 基本使用
greeting = f"你好,我的名字是 {name},我今年 {age} 岁。"
print(greeting) # 输出:你好,我的名字是 Alice,我今年 30 岁。
# 嵌入表达式
next_year_age = f"明年我将是 {age + 1} 岁。"
print(next_year_age) # 输出:明年我将是 31 岁。
# 调用函数
def get_status():
return "在线"
status_msg = f"用户 {name} 当前状态:{get_status()}。"
print(status_msg) # 输出:用户 Alice 当前状态:在线。
# 格式化选项 (类似 format() 的微语言)
formatted_temp = f"当前温度是 {temperature:.1f}°C。" # 保留一位小数
print(formatted_temp) # 输出:当前温度是 25.5°C。
# 调试利器 (Python 3.8+)
debug_info = f"{name=}, {age=}"
print(debug_info) # 输出:name='Alice', age=30f-string 的强大之处在于其直接和“活生生”的感觉,你写什么,它就计算什么,几乎没有额外的语法负担。
str.format()
%
{}.format()
name = "Bob"
item = "书"
price = 19.99
# 位置参数
message_pos = "我买了一本 {},花了 {} 元。".format(item, price)
print(message_pos) # 输出:我买了一本 书,花了 19.99 元。
# 索引参数 (可以改变顺序)
message_indexed = "我买了 {1},花了 {0} 元。".format(price, item)
print(message_indexed) # 输出:我买了 书,花了 19.99 元。
# 关键字参数 (更具可读性)
message_kw = "用户 {user} 购买了 {product},总计 {cost:.2f} 元。".format(user="Charlie", product="笔记本", cost=120.5)
print(message_kw) # 输出:用户 Charlie 购买了 笔记本,总计 120.50 元。
# 访问对象属性或字典键
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
p = Product("键盘", 99.0)
product_info = "商品名称:{0.name},价格:{0.price:.2f} 元。".format(p)
print(product_info) # 输出:商品名称:键盘,价格:99.00 元。
data = {'city': 'London', 'temp': 15}
weather_report = "城市:{city},气温:{temp}°C。".format(**data) # 使用字典解包
print(weather_report) # 输出:城市:London,气温:15°C。.format()
%
printf
%
%s
%d
%f
name = "David"
score = 95
pi = 3.14159
# 单个变量
msg_single = "学生姓名: %s" % name
print(msg_single) # 输出:学生姓名: David
# 多个变量 (元组形式)
msg_multi = "学生 %s 的分数是 %d。" % (name, score)
print(msg_multi) # 输出:学生 David 的分数是 95。
# 浮点数精度控制
msg_float = "圆周率大约是 %.2f。" % pi
print(msg_float) # 输出:圆周率大约是 3.14。
# 字典形式 (通过键名引用)
data_dict = {'user': 'Eve', 'level': 7}
msg_dict = "用户 %(user)s 当前等级 %(level)d。" % data_dict
print(msg_dict) # 输出:用户 Eve 当前等级 7。%
f-string 简直就是现代 Python 字符串格式化的“瑞士军刀”,我个人几乎所有新代码都倾向于用它。它之所以能迅速成为社区的新宠,并被认为是“优雅”的代表,主要有几个原因。
首先是它的极致简洁与直观。你不需要像
format()
%
{}f"用户年龄是 {user.age} 岁。""{user.age} 岁。".format(user=user)"用户年龄是 %d 岁。" % user.age
其次,性能上的优势也是一个不容忽视的因素。虽然对于大多数应用来说,这点差异可能微不足道,但在处理大量字符串拼接或在性能敏感的循环中,f-string 通常比
.format()
%
再者,f-string 提供了强大的表达式支持。你可以在大括号内进行算术运算、函数调用、方法调用,甚至是条件表达式。这让字符串的构建变得异常灵活,很多以前需要先计算好再传入的中间变量,现在可以直接在字符串内部完成。比如
f"明天是 {datetime.date.today() + datetime.timedelta(days=1)}"f"{variable=}"最后,从代码维护的角度来看,f-string 能够更好地将格式与数据绑定在一起。当你在阅读代码时,所有相关的变量和表达式都在字符串的上下文里,上下文切换的成本更低。这对于团队协作和长期维护的项目来说,无疑是一个巨大的福音。我曾维护过一些老项目,里面充斥着复杂的
%
str.format()
尽管 f-string 强大且优雅,但它并非万能药,有些场景下,
str.format()
f-string 的一个核心特性是它在定义时就立即求值。这意味着,f-string 本身不能作为模板存储在一个变量中,然后在稍后传入数据。比如,你不能写
template = f"Hello, {name}!"name
name
template
而
str.format()
举个例子,假设你正在开发一个国际化(i18n)的应用。不同语言的句子结构可能完全不同,变量的顺序也可能需要调整。
# 假设这是从语言包加载的
english_template = "Hello, {name}! You have {count} unread messages."
chinese_template = "{name},你好!你有 {count} 条未读消息。"
user_name = "Anna"
unread_count = 5
print(english_template.format(name=user_name, count=unread_count))
print(chinese_template.format(name=user_name, count=unread_count))在这里,
english_template
chinese_template
.format()
此外,在需要传递格式字符串给函数或方法,让它们来处理实际的数据填充时,
str.format()
def log_message(template, **kwargs):
# 可以在这里添加日志级别、时间戳等逻辑
print(f"[LOG] {template.format(**kwargs)}")
log_message("用户 {username} 登录失败,IP: {ip_address}", username="guest", ip_address="192.168.1.1")在这种情况下,
template
str.format()
log_message
所以,虽然 f-string 是我的首选,但在需要将格式字符串本身作为数据处理,或者为了向后兼容(Python 3.5及以下版本不支持 f-string)时,
str.format()
%
老实说,除非我是在维护一个古董级的 Python 2 项目,否则我几乎不会主动去使用
%
str.format()
首先,可读性差是最大的痛点。当你要插入的变量数量一多,或者需要进行复杂的格式控制时,那个
%s
%d
%.2f
data = ("John", 25, 1.80, "male")
message = "Name: %s, Age: %d, Height: %.2f meters, Gender: %s" % data
# 如果我不小心把元组顺序弄错了,或者类型不匹配,比如把 'male' 传给了 %d,程序就会崩溃。这与 f-string 的
f"Name: {name}, Age: {age}, Height: {height:.2f} meters, Gender: {gender}"其次,功能相对有限。
%
str.format()
%(key)s
.format(key=value)
f"{dict['key']}"再者,潜在的安全问题。虽然这不是一个普遍的漏洞,但在某些特定场景下,如果格式字符串本身来自不可信的用户输入,并且没有经过严格的过滤,可能会导致意外的行为。当然,这更多是编程实践的问题,但
str.format()
那么,如果你不幸接手了一个大量使用
%
逐步替换,优先处理新代码和修改频繁的代码:没必要一下子把所有
%
str.format()
%
利用 IDE 或工具进行辅助:许多现代 IDE(如 PyCharm, VS Code)都提供了代码检查功能,可以识别并建议将
%
str.format()
%
从简单的开始:
"Hello %s" % name
f"Hello {name}""Name: %s, Age: %d" % (name, age)
f"Name: {name}, Age: {age}""User %(name)s, ID %(id)d" % user_dict
f"User {user_dict['name']}, ID {user_dict['id']}"f"User {name}, ID {id}"name
id
注意格式化细节的转换:
%.2f
{variable:.2f}%03d
{variable:03d}%-10s
{variable:<10}%10s
{variable:>10}str.format()
测试是关键:无论你做了多小的改动,都务必运行相应的单元测试和集成测试,确保格式化后的输出与之前完全一致,没有引入新的 bug。
总之,
%
str.format()
以上就是如何优雅地格式化字符串?(f-string, format, %)的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号