Python字符串格式化方法与最佳实践
1. Python字符串格式化基础字符串格式化是Python编程中最常用的功能之一它允许我们将变量值插入到字符串模板中。Python提供了多种字符串格式化方法每种方法都有其特点和适用场景。1.1 百分号(%)格式化这是Python最早的字符串格式化方法语法类似于C语言的printfname Alice age 25 print(My name is %s and Im %d years old. % (name, age))常用格式说明符%s字符串%d十进制整数%f浮点数%x十六进制整数提示这种格式化方式在Python 3中仍然可用但官方推荐使用更新的格式化方法。1.2 str.format()方法Python 2.6引入的格式化方法提供了更强大的功能print(My name is {} and Im {} years old..format(name, age))支持的特性包括位置参数{0},{1}关键字参数{name},{age}属性访问{obj.attr}格式化选项{:.2f}保留两位小数2. f-string格式化Python 3.6f-string是Python 3.6引入的字符串字面量格式化语法是目前最推荐的格式化方式。2.1 基本用法print(fMy name is {name} and Im {age} years old.)f-string特点在字符串前加f或F前缀表达式写在{}中直接引用当前作用域的变量2.2 高级特性# 表达式计算 print(fNext year Ill be {age 1} years old.) # 调用方法 print(fMy name in uppercase: {name.upper()}) # 格式化数字 pi 3.1415926 print(fPi rounded to 2 decimals: {pi:.2f}) # 对齐和填充 print(fName: {name:10} Age: {age:5})3. 字符串模板(Template)string模块提供的Template类实现了一种简单的字符串替换机制from string import Template t Template(My name is $name and I\m $age years old.) print(t.substitute(nameBob, age30))特点使用$作为占位符前缀safe_substitute()方法可避免缺少键时抛出异常适合处理用户提供的模板4. 常用字符串模块4.1 string模块常量string模块定义了许多有用的字符串常量import string print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ print(string.digits) # 0123456789 print(string.punctuation) # 所有标点符号 print(string.whitespace) # 所有空白字符4.2 字符串操作函数# 大小写转换 print(hello.capitalize()) # Hello print(HELLO.lower()) # hello # 查找和替换 print(hello world.find(world)) # 6 print(hello hello.replace(hello, hi, 1)) # hi hello # 拆分和连接 print(a,b,c.split(,)) # [a, b, c] print(-.join([a, b, c])) # a-b-c # 去除空白 print( hello .strip()) # hello5. 字符串格式化高级技巧5.1 自定义格式化通过实现__format__方法可以自定义对象的格式化行为class Point: def __init__(self, x, y): self.x x self.y y def __format__(self, format_spec): if format_spec polar: import math r math.hypot(self.x, self.y) theta math.atan2(self.y, self.x) return fr{r:.2f}, θ{theta:.2f} return f({self.x}, {self.y}) p Point(3, 4) print(fCartesian: {p}) # Cartesian: (3, 4) print(fPolar: {p:polar}) # Polar: r5.00, θ0.935.2 本地化数字格式化使用locale模块实现本地化的数字格式化import locale locale.setlocale(locale.LC_ALL, en_US.UTF-8) number 1234567.89 print(locale.format_string(%.2f, number, groupingTrue)) # 1,234,567.895.3 性能比较不同格式化方法的性能差异f-string最快编译时求值str.format()中等%格式化较慢Template最慢适合安全性要求高的场景6. 实际应用示例6.1 日志消息格式化import logging logging.basicConfig(format%(asctime)s - %(levelname)s - %(message)s) logging.warning(fUser {name} performed an action at {datetime.now()})6.2 数据报表生成data [ {product: Apple, price: 1.2, quantity: 50}, {product: Banana, price: 0.5, quantity: 120}, {product: Orange, price: 0.8, quantity: 75} ] # 生成表格 header f{Product:10} | {Price:8} | {Quantity:10} separator - * len(header) rows [ f{item[product]:10} | {item[price]:8.2f} | {item[quantity]:10d} for item in data ] print(\n.join([header, separator] rows))6.3 配置文件模板from string import Template config_template Template( [database] host $host port $port username $user password $password ) config config_template.substitute( hostlocalhost, port5432, useradmin, passwordsecret ) print(config)7. 常见问题与解决方案7.1 大括号转义当需要在f-string或format中使用字面量大括号时# f-string print(f{{This is in curly braces}}) # {This is in curly braces} # format print({{This is in curly braces}}.format()) # 同上7.2 动态格式化# 动态决定格式化方式 format_spec .2f print(fValue: {3.1415926:{format_spec}}) # Value: 3.14 # 从字典动态获取值 data {name: Alice, age: 25} print(Name: {name}, Age: {age}.format(**data))7.3 处理缺失键from collections import defaultdict data {name: Bob} safe_data defaultdict(lambda: N/A, data) # 使用get()方法 print(Name: {name}, Age: {age}.format_map(safe_data)) # Name: Bob, Age: N/A # 使用Template的safe_substitute t Template(Name: $name, Age: $age) print(t.safe_substitute(data)) # Name: Bob, Age: $age8. 字符串格式化的最佳实践Python 3.6优先使用f-string语法简洁性能最佳复杂格式化使用str.format()当格式化字符串需要重复使用或来自外部时用户提供的模板使用Template安全性更高保持一致性在项目中统一格式化风格考虑可读性过于复杂的表达式应拆分为多行国际化考虑使用gettext等工具处理多语言场景# 可读性示例 name Alice age 25 score 95.5 # 不推荐过于复杂 print(f{name} ({age}): {PASS if score 60 else FAIL} ({score:.1f}%)) # 推荐拆分逻辑 result PASS if score 60 else FAIL formatted_score f{score:.1f}% print(f{name} ({age}): {result} ({formatted_score}))