如何在Python中正确使用格式化字符串

在Python编程中,字符串格式化是一项基础且重要的技能。无论是简单的日志输出,还是复杂的数据展示,掌握好字符串格式化都能让代码更加优雅和高效。本文将深入浅出地介绍Python中各种字符串格式化方法,帮助你选择最适合的方案。

一、Python字符串格式化的演进历程

Python的字符串格式化经历了三个重要阶段:

  • Python 2:%-formatting(模仿C语言的printf)

  • Python 3.0:str.format() 方法

  • Python 3.6:f-strings(最现代的方式)

二、三种主要的格式化方式详解

1. %-formatting(传统方式)

这是Python最古老的字符串格式化方法,使用%操作符。

python
# 基本用法
name = "Alice"
age = 25
print("My name is %s and I'm %d years old" % (name, age))

# 常用格式化符号
# %s - 字符串
# %d - 整数
# %f - 浮点数
# %x - 十六进制

# 格式化数字
pi = 3.14159
print("Pi is %.2f" % pi)  # 保留两位小数:3.14

# 使用字典
data = {'name': 'Bob', 'age': 30}
print("Name: %(name)s, Age: %(age)d" % data)

优点:简单直观,适合简单场景
缺点:类型限制严格,可读性差,容易出错

2. str.format() 方法(过渡方式)

Python 3.0引入,提供了更强大的功能。

python
# 基本用法
name = "Charlie"
age = 35
print("My name is {} and I'm {} years old".format(name, age))

# 使用索引
print("My name is {0} and I'm {1} years old".format(name, age))

# 使用参数名
print("My name is {name} and I'm {age} years old".format(name=name, age=age))

# 格式化数字
pi = 3.14159
print("Pi is {:.2f}".format(pi))  # 3.14

# 对齐和填充
print("{:<10} is left aligned".format("Text"))   # 左对齐
print("{:>10} is right aligned".format("Text"))  # 右对齐
print("{:^10} is centered".format("Text"))       # 居中
print("{:*^10}".format("Text"))                   # 居中使用*填充

# 千位分隔符
large_num = 1000000
print("{:,}".format(large_num))  # 1,000,000

# 日期格式化
from datetime import datetime
now = datetime.now()
print("{:%Y-%m-%d %H:%M}".format(now))

优点:功能强大,灵活性强
缺点:语法略显冗长

3. f-strings(推荐方式)

Python 3.6引入,是目前最推荐的格式化方式。

python
# 基本用法
name = "David"
age = 40
print(f"My name is {name} and I'm {age} years old")

# 表达式求值
a, b = 5, 3
print(f"{a} + {b} = {a + b}")
print(f"{a} > {b} is {a > b}")

# 调用函数
def greet(name):
    return f"Hello, {name}"

print(f"Message: {greet('Eve')}")

# 格式化数字
pi = 3.14159
print(f"Pi is {pi:.2f}")  # 3.14

# 对齐和填充
text = "Python"
print(f"{text:<10} left")
print(f"{text:>10} right")
print(f"{text:^10} center")

# 字典访问
person = {'name': 'Frank', 'age': 45}
print(f"{person['name']} is {person['age']} years old")

# 调试功能(Python 3.8+)
x = 42
print(f"{x = }")  # 输出:x = 42
print(f"{x = :#x}")  # 十六进制:x = 0x2a

# 多行f-string
name = "Grace"
age = 28
message = (
    f"Name: {name}\n"
    f"Age: {age}\n"
    f"Next year: {age + 1}"
)
print(message)

优点:简洁、直观、性能好、支持表达式
缺点:只能在Python 3.6+使用

三、实战案例

1. 日志记录

python
import logging
from datetime import datetime

# 使用f-strings记录日志
def log_user_action(user_id, action, status):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log_msg = f"[{timestamp}] User {user_id}: {action} - {status}"
    print(log_msg)  # 实际项目中会使用logging模块

log_user_action(1001, "login", "success")

2. 数据报表生成

python
def generate_report(products):
    """生成商品销售报表"""
    print("=" * 50)
    print(f"{'Product':<20} {'Price':>10} {'Sold':>10} {'Total':>10}")
    print("=" * 50)
    
    total_revenue = 0
    for product in products:
        total = product['price'] * product['sold']
        total_revenue += total
        print(f"{product['name']:<20} ${product['price']:>9.2f} "
              f"{product['sold']:>10} ${total:>9.2f}")
    
    print("=" * 50)
    print(f"{'TOTAL REVENUE:':<40} ${total_revenue:>9.2f}")

# 测试数据
products = [
    {'name': 'Laptop', 'price': 999.99, 'sold': 5},
    {'name': 'Mouse', 'price': 29.99, 'sold': 20},
    {'name': 'Keyboard', 'price': 79.99, 'sold': 10}
]

generate_report(products)

3. 进度条显示

python
import time

def show_progress(iterations=50):
    """显示简单的进度条"""
    for i in range(iterations + 1):
        percent = (i / iterations) * 100
        filled = int(i / iterations * 30)
        bar = "█" * filled + "░" * (30 - filled)
        print(f"\rProgress: |{bar}| {i}/{iterations} ({percent:.1f}%)", 
              end="", flush=True)
        time.sleep(0.05)
    print()  # 换行

show_progress()

四、性能对比

python
import timeit

# 测试各种格式化方法的性能
name = "Python"
version = 3.9

def test_percent():
    return "Hello %s, version %.1f" % (name, version)

def test_format():
    return "Hello {}, version {:.1f}".format(name, version)

def test_fstring():
    return f"Hello {name}, version {version:.1f}"

# 执行性能测试
percent_time = timeit.timeit(test_percent, number=1000000)
format_time = timeit.timeit(test_format, number=1000000)
fstring_time = timeit.timeit(test_fstring, number=1000000)

print(f"%-formatting: {percent_time:.4f} seconds")
print(f"str.format(): {format_time:.4f} seconds")
print(f"f-strings:    {fstring_time:.4f} seconds")

五、最佳实践建议

✅ 推荐的做法

  1. 优先使用f-strings(Python 3.6+)

python
# 好的做法
name = "Alice"
print(f"Hello, {name}")
  1. 复杂格式化使用str.format()

python
# 当需要重复使用模板时
template = "Hello, {name}. You are {age} years old."
print(template.format(name="Bob", age=25))
  1. 多行字符串处理

python
# 使括号组织多行
query = (
    f"SELECT * FROM users "
    f"WHERE age > {min_age} "
    f"ORDER BY name"
)

❌ 需要避免的做法

  1. 避免过于复杂的表达式

python
# 不推荐
print(f"Result: {[x**2 for x in range(10) if x % 2 == 0]}")

# 推荐
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(f"Result: {even_squares}")
  1. 避免在日志中使用f-strings

import logging

# 不推荐
logging.error(f"Error: {error_msg}")  # 即使日志级别不匹配也会执行

# 推荐
logging.error("Error: %s", error_msg)  # 延迟格式化,提升性能

六、常见问题解答

Q1: f-strings和str.format()哪个更快?
A: f-strings通常更快,因为它在编译时就确定了格式,而不是运行时解析。

Q2: 如何在f-string中使用大括号?

python
# 使用双大括号
print(f"{{}} 是字典的表示")  # 输出:{} 是字典的表示

Q3: f-string可以嵌套吗?

python
# f-string嵌套
width = 10
text = "Python"
print(f"{text:>{width}}")  # 右对齐,宽度10

总结

选择合适的字符串格式化方法:

  • 如果使用Python 3.6+,优先选择f-strings

  • 需要兼容旧版本Python时,使用str.format()

  • 简单的字符串拼接,可以使用+

  • 日志记录等场景,使用%-formatting延迟格式化

掌握这些技巧,相信你的Python代码会更加简洁、高效和易读。记住,选择什么方法取决于具体场景,没有绝对的”最好”,只有”最合适”。

购买须知/免责声明
1.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
2.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
3.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
4.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
5.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
6.不保证任何源码框架的完整性。
7.侵权联系邮箱:aliyun6168@gail.com / aliyun666888@gail.com
8.若您最终确认购买,则视为您100%认同并接受以上所述全部内容。

小璐导航资源站 Python 如何在Python中正确使用格式化字符串 https://o789.cn/25089.html

相关文章

猜你喜欢