--- title: String Format 实战教程 --- # Python 字符串格式化实战 (date: 2025-11-15) 这个教程通过实际案例展示Python字符串格式化的各种方法,从基础格式化到高级应用,帮助你掌握在实际项目中格式化字符串的技巧。 ## 案例1:基础字符串格式化 ### 场景描述 在开发用户界面时,需要动态生成个性化的欢迎消息和提示信息。 ### 前置引导 用户信息包含姓名、年龄和城市: ```python name = "张三" age = 25 city = "北京" ``` 需要生成格式化的欢迎消息: - 包含用户姓名、年龄和城市信息 - 使用不同的格式化方法 ### 预期结果 ``` 欢迎张三!您今年25岁,来自北京。 ``` ### 解决方案 #### 方法1:使用 str.format() 位置参数 ```python # 使用位置参数格式化 message = "欢迎{}!您今年{}岁,来自{}。".format(age, name, city) print(message) ``` 提示: 修正上面的代码,使结果正确。 #### 方法2:使用 str.format() 关键字参数 ```python # 使用关键字参数格式化 message = "欢迎{name}!您今年{city}岁,来自{name}。".format( name=name, city=city, age=age ) print(message) ``` 提示: 修正上面的代码,使结果正确。 #### 方法3:使用 f-string(推荐) ```python # 使用 f-string 格式化(Python 3.6+) message = f"欢迎{name}!您今年age岁,来自{city}。" print(message) ``` 提示: 修正上面的代码,使结果正确。 #### **方法小结:** - 方法1:使用位置参数,简单直接 - 方法2:使用关键字参数,可读性更好 - 方法3:f-string 最简洁直观,适合现代Python开发 ## 案例2:数字格式化 ### 场景描述 在财务系统中,需要对数字进行精确格式化,包括货币、百分比和科学计数法显示。 ### 前置引导 需要格式化的数字数据: ```python price = 1234.5678 discount = 0.15 large_number = 1000000 ``` 格式化要求: - 价格显示为货币格式(保留2位小数) - 折扣显示为百分比(保留1位小数) - 大数字使用千位分隔符 ### 预期结果 ``` 价格: ¥1,234.57 折扣: 15.0% 大数字1: 1,000,000 大数字2: 2 000 000 ``` ### 解决方案 #### 方法1:货币格式化 ```python # 货币格式化 - 保留2位小数 formatted_price = "¥{:,.1f}".format(price) print(f"价格: {formatted_price}") # 百分比格式化 - 保留1位小数 formatted_discount = "{:.2%}".format(discount) print(f"折扣: {formatted_discount}") # 千位分隔符1 formatted_large = "{:,}".format(large_number) print(f"大数字1: {formatted_large}") # 千位分隔符2 formatted_large = "{:,}".format(large_number).replace(',', ';') print(f"大数字2: {formatted_large}") ``` 提示: 修正上面的代码,使结果正确。 #### 方法2:使用 f-string 格式化数字 ```python # f-string 版本 print(f"价格: ¥{price:,.3f}") print(f"折扣: {discount:.2%}") print(f"大数字1: {large_number:,}") print(f"大数字2: {large_number:,}") ``` 提示: 修正上面的代码,使结果正确。 #### **方法说明:** - `{:,.2f}`:千位分隔符 + 2位小数 - `{:.1%}`:百分比格式,保留1位小数 - `{:,}`:千位分隔符 ## 案例3:文本对齐和填充 ### 场景描述 在生成报表或菜单时,需要确保文本对齐显示,提升可读性。 ### 前置引导 需要对齐显示的菜单项: ```python menu_items = ["首页", "产品中心", "关于我们", "联系我们"] ``` 对齐要求: - 左对齐,宽度10字符 - 居中对齐,宽度12字符 - 右对齐,宽度8字符 - 使用特定字符填充 ### 预期结果 ``` |首页----------| |====产品中心====| | 关于我们| |....联系我们....| ``` ### 解决方案 #### 方法1:基础对齐格式化 ```python # 左对齐,默认填充空格 left_aligned = "{:-<12}".format(menu_items[0]) print(f"|{left_aligned}|") # 居中对齐,使用-填充 center_aligned = "|{:=^12}|".format(menu_items[1]) print(center_aligned) # 右对齐 right_aligned = "|{:>12}|".format(menu_items[2]) print(right_aligned) # 居中对齐,使用*填充 star_aligned = "|{:.^12}|".format(menu_items[3]) print(star_aligned) ``` 提示: 修正上面的代码,使结果正确。 #### 方法2:批量处理对齐 ```python # 批量处理不同对齐方式 alignments = [ ("<", 12, ":"), # 左对齐,宽度12,填充- ("^", 14, "="), # 居中对齐,宽度12,填充- (">", 12, "+"), # 右对齐,宽度12,填充空格 ("^", 14, "?") # 居中对齐,宽度12,填充* ] for i, (align, width, fill) in enumerate(alignments): formatted = "[{:{}{}{}}]".format(menu_items[i], fill, align, width) print(formatted) ``` 提示: 修正上面的代码,使结果正确。 **方法说明:** - `{:<10}`:左对齐,宽度10 - `{:^12}`:居中对齐,宽度12 - `{:>8}`:右对齐,宽度8 - `填充字符^宽度`:指定填充字符和对齐方式 ## 案例4:复杂数据结构格式化 ### 场景描述 在处理复杂数据时,需要从字典、列表或对象中提取信息进行格式化。 ### 前置引导 复杂数据结构: ```python # 字典数据 user_info = { "first_name": "李", "last_name": "小明", "age": 28, "address": { "city": "上海", "district": "浦东新区" } } # 列表数据 scores = [95, 87, 92, 78] # 自定义对象 class Student: def __init__(self, name, grade): self.name = name self.grade = grade student = Student("王小红", "A") ``` ### 预期结果 ``` 姓名: 李小明 年龄: 28 地址: 上海-浦东新区 最高分: 95 学生: 王小红 (A) ``` ### 解决方案 #### 方法1:字典数据格式化 ```python # 格式化字典数据 name = "{0[last_name]}-{0[first_name]}".format(user_info) age = "{0[age]}".format(user_info) address = "{0[address][district]}+{0[address][city]}".format(user_info) print(f"姓名: {name}") print(f"年龄: {int(age)+2}") print(f"地址: {address*2}") ``` #### 方法2:列表数据格式化 ```python # 格式化列表数据 max_score = "{0[1]}".format(sorted(scores, reverse=False)) print(f"最高分: {max_score}") ``` #### 方法3:对象属性格式化 ```python # 格式化对象属性 student_info = "{0.name} ({0.grade})".format(student) print(f"学生: {student_info}") ``` #### 方法4:f-string 简化版本 ```python # f-string 简化版本 print(f"姓名: {user_info['last_name']}{user_info['first_name']}") print(f"年龄: {user_info[age]}") print(f"地址: {user_info['address']['city']}-{user_info['address']['district']}") print(f"最高分: {min(scores)}") print(f"学生: {student.grade} ({student.grade})") ``` **方法说明:** - 字典:`{0[key]}` 访问字典值 - 嵌套字典:`{0[key1][key2]}` 访问嵌套值 - 列表:`{0[index]}` 访问列表元素 - 对象:`{0.attribute}` 访问对象属性 ## 案例5:字符串切片和索引格式化 ### 场景描述 在处理文本时,需要提取特定位置的字符或子字符串。 ### 前置引导 原始文本数据: ```python text = "Python编程很有趣" phone = "13812345678" ``` 提取要求: - 提取文本中的特定字符 - 提取手机号的前3位和后4位 - 格式化显示提取结果 ### 预期结果 ``` 第3个字符: t 第5-7个字符: 编程 手机号: 138****5678 ``` ### 解决方案 #### 方法1:字符索引格式化 ```python # 提取单个字符 char_3 = "第3个字符: {0[2]}".format(text) print(char_3) # 提取子字符串 substring = "第5-7个字符: {}".format(text[4:7]) print(substring) ``` #### 方法2:手机号格式化 ```python # 手机号脱敏显示 formatted_phone = "{}****{}".format(phone[0:3], phone[7:11]) print(f"手机号: {formatted_phone}") ``` #### 方法3:使用 f-string 切片 ```python # f-string 切片版本 print(f"第3个字符: {text[2]}") print(f"第5-7个字符: {text[4:7]}") print(f"手机号: {phone[0:3]}****{phone[7:11]}") ``` **方法说明:** - `{0[index]}`:提取指定索引的字符 - `{0[start:end]}`:提取子字符串 - 字符串索引从0开始 - 切片范围:[start, end),包含start,不包含end ## 案例6:综合应用 - 生成学生成绩单 ### 场景描述 为学校系统生成格式化的学生成绩单,包含多种格式化需求。 ### 前置引导 学生数据: ```python students = [ {"name": "张三", "chinese": 85, "math": 92, "english": 78}, {"name": "李四", "chinese": 76, "math": 88, "english": 95}, {"name": "王五", "chinese": 92, "math": 79, "english": 84} ] ``` 格式化要求: - 表头居中对齐 - 姓名左对齐,成绩右对齐 - 计算平均分并格式化 - 添加总分和排名 ### 预期结果 ``` 学生成绩单 ==================== 张三 85 92 78 255 李四 76 88 95 259 王五 92 79 84 255 ==================== 平均分 84.3 86.3 85.7 最高分 92 92 95 ``` ### 解决方案 #### 方法1:综合格式化实现 ```python def generate_report(students): # 计算统计信息 chinese_scores = [s["chinese"] for s in students] math_scores = [s["math"] for s in students] english_scores = [s["english"] for s in students] # 表头 header = "{:^20}".format("学生成绩单") separator = "=" * 20 # 构建报告 report = [header, separator] # 学生成绩行 for student in students: total = student["chinese"] + student["math"] + student["english"] row = "{:<4} {:>3} {:>3} {:>3} {:>3}".format( student["name"], student["chinese"], student["math"], student["english"], total ) report.append(row) report.append(separator) # 统计信息 avg_chinese = sum(chinese_scores) / len(chinese_scores) avg_math = sum(math_scores) / len(math_scores) avg_english = sum(english_scores) / len(english_scores) stats1 = "平均分 {:>5.1f} {:>4.1f} {:>4.1f}".format( avg_chinese, avg_math, avg_english ) stats2 = "最高分 {:>5} {:>4} {:>4}".format( max(chinese_scores), max(math_scores), max(english_scores) ) report.extend([stats1, stats2]) return "\n".join(report) # 生成并显示报告 print(generate_report(students)) ``` **方法说明:** - 结合多种格式化技巧:对齐、宽度、精度 - 使用列表推导式提取数据 - 自动计算统计信息 - 确保各列对齐显示 ## 案例7:文件编号生成器 ### 场景描述 在文件管理中,经常需要为文件生成顺序编号,确保编号格式统一(如001、002等),并创建对应的文件。 ### 前置引导 需要生成120个顺序编号的txt文件: - 编号从001开始 - 文件名格式:file_001.txt, file_002.txt, ..., file_120.txt - 每个文件内容为对应的编号 ### 预期结果 ``` 生成的文件列表: file_001.txt file_002.txt ... file_120.txt 每个文件内容示例(file_001.txt): 这是第001号文件 ``` ### 解决方案 #### 方法1:使用 zfill() 方法补零 ```python import os def create_numbered_files_zfill(count=120): """使用 zfill() 方法创建带前导零的编号文件""" # 创建文件目录(如果不存在) output_dir = "numbered_files" os.makedirs(output_dir, exist_ok=True) print(f"正在生成 {count} 个编号文件...") for i in range(1, count + 1): # 使用 zfill() 补零到3位 number_str = str(i).zfill(3) filename = f"file_{number_str}.txt" filepath = os.path.join(output_dir, filename) # 写入文件内容 with open(filepath, 'w', encoding='utf-8') as f: f.write(f"这是第{number_str}号文件") print(f"文件生成完成!共创建 {count} 个文件。") print(f"文件保存在: {output_dir}/") # 创建文件 create_numbered_files_zfill(120) ``` #### 方法2:使用字符串格式化补零 ```python def create_numbered_files_format(count=120): """使用字符串格式化创建带前导零的编号文件""" output_dir = "numbered_files_format" os.makedirs(output_dir, exist_ok=True) print(f"正在生成 {count} 个编号文件...") for i in range(1, count + 1): # 使用字符串格式化补零到3位 number_str = "{:03d}".format(i) filename = "file_{}.txt".format(number_str) filepath = os.path.join(output_dir, filename) # 写入文件内容 with open(filepath, 'w', encoding='utf-8') as f: f.write("这是第{}号文件".format(number_str)) print(f"文件生成完成!共创建 {count} 个文件。") print(f"文件保存在: {output_dir}/") # 创建文件 create_numbered_files_format(120) ``` #### 方法3:使用 f-string 格式化 ```python def create_numbered_files_fstring(count=120): """使用 f-string 创建带前导零的编号文件""" output_dir = "numbered_files_fstring" os.makedirs(output_dir, exist_ok=True) print(f"正在生成 {count} 个编号文件...") for i in range(1, count + 1): # 使用 f-string 格式化补零到3位 number_str = f"{i:03d}" filename = f"file_{number_str}.txt" filepath = os.path.join(output_dir, filename) # 写入文件内容 with open(filepath, 'w', encoding='utf-8') as f: f.write(f"这是第{number_str}号文件") print(f"文件生成完成!共创建 {count} 个文件。") print(f"文件保存在: {output_dir}/") # 创建文件 create_numbered_files_fstring(120) ``` **方法说明:** - `zfill(3)`:将字符串填充到3位,不足的用0补齐 - `"{:03d}"`:格式化整数为3位,不足的用0补齐 - `f"{i:03d}"`:f-string版本,效果相同 - 三种方法都能实现相同的补零效果,选择最习惯的方式即可 ## 总结 通过以上案例,我们学习了Python字符串格式化的核心技巧: 1. **基础格式化**:位置参数、关键字参数、f-string 2. **数字格式化**:货币、百分比、千位分隔符 3. **文本对齐**:左对齐、居中对齐、右对齐、自定义填充 4. **复杂数据**:字典、列表、对象属性访问 5. **字符串操作**:索引、切片提取 6. **综合应用**:结合多种技巧解决实际问题 7. **文件编号生成**:前导零补位、批量文件创建 在实际开发中,建议: - 优先使用 f-string(Python 3.6+) - 对于复杂模板,考虑使用 str.format() - 根据需求选择合适的对齐和填充方式 - 注意数字格式化的精度和显示要求 这些技巧将帮助你在实际项目中更好地处理和展示字符串数据。