Python f-strings:格式化字符串字面量完整指南
Updated on
Python 的字符串格式化在多年间演进出了多种写法,每一种都或多或少存在冗长和可读性问题。老式的 % 格式化语法晦涩难懂,而 .format() 往往会用编号占位符写出不必要的长代码。这些方式让简单的字符串插值变得像在解谜,而不是在写清晰、可维护的代码。
当你需要按指定精度格式化数字、在表格中对齐文本,或在一行里调试变量值时,这种挫败感会更强。传统方法把逻辑分散在格式字符串和参数列表之间,使你很难一眼看出最终输出长什么样。在做数据分析与报告任务时,你会花更多时间和字符串格式化语法较劲,而不是专注于真正的分析。
Python 3.6 引入了 f-strings(formatted string literals,格式化字符串字面量),作为现代且优雅的字符串格式化解决方案。通过在字符串前加上 f 前缀,并在大括号中直接嵌入表达式,f-strings 提供了 Python 中最可读、性能也最好的字符串插值方式。本指南将从基础用法讲到高级格式化技巧,彻底改变你处理字符串的方式。
基础 f-string 语法
F-strings 使用非常简单的前缀标记:在字符串开引号前加上 f 或 F。在字符串内部,任何用大括号包起来的表达式都会被求值,并插入到最终输出中。
name = "Alice"
age = 30
# Basic f-string
message = f"My name is {name} and I am {age} years old"
print(message)
# Output: My name is Alice and I am 30 years old
# Using uppercase F
greeting = F"Hello, {name}!"
print(greeting)
# Output: Hello, Alice!当你把它与旧方法对比时,f-strings 的优势会非常明显:
name = "Bob"
score = 95.5
# Old style % formatting
old_way = "Student: %s, Score: %.1f" % (name, score)
# str.format() method
format_way = "Student: {}, Score: {:.1f}".format(name, score)
# Modern f-string
f_string_way = f"Student: {name}, Score: {score:.1f}"
print(f_string_way)
# Output: Student: Bob, Score: 95.5变量插值与表达式
F-strings 不仅能处理变量——它们还能在大括号内求值任何合法的 Python 表达式。这包括算术运算、方法调用、列表推导式以及函数调用等。
# Arithmetic expressions
x = 10
y = 5
result = f"{x} + {y} = {x + y}"
print(result)
# Output: 10 + 5 = 15
# String methods
text = "python"
formatted = f"Language: {text.upper()}, Length: {len(text)}"
print(formatted)
# Output: Language: PYTHON, Length: 6
# Dictionary and list access
user = {"name": "Charlie", "role": "developer"}
scores = [88, 92, 95]
info = f"{user['name']} is a {user['role']} with average score {sum(scores)/len(scores):.1f}"
print(info)
# Output: Charlie is a developer with average score 91.7你可以在 f-string 中直接调用函数,使复杂的格式化操作变得异常简洁:
def calculate_discount(price, discount_percent):
return price * (1 - discount_percent / 100)
price = 100
discount = 20
message = f"Original: ${price}, Final: ${calculate_discount(price, discount):.2f}"
print(message)
# Output: Original: $100, Final: $80.00
# List comprehension inside f-string
numbers = [1, 2, 3, 4, 5]
result = f"Squares: {[n**2 for n in numbers]}"
print(result)
# Output: Squares: [1, 4, 9, 16, 25]数字格式化技巧
F-strings 通过紧跟在冒号后的格式说明符(format specifier)提供了丰富的数字格式化选项。通用语法为 {value:format_spec}。
小数位与精度
pi = 3.14159265359
# Different decimal places
print(f"2 decimals: {pi:.2f}")
print(f"4 decimals: {pi:.4f}")
print(f"0 decimals: {pi:.0f}")
# Output:
# 2 decimals: 3.14
# 4 decimals: 3.1416
# 0 decimals: 3千分位分隔符
large_number = 1234567890
# Comma separator
print(f"With commas: {large_number:,}")
# Output: With commas: 1,234,567,890
# Underscore separator (Python 3.6+)
print(f"With underscores: {large_number:_}")
# Output: With underscores: 1_234_567_890
# Combining separators with decimal places
revenue = 1234567.89
print(f"Revenue: ${revenue:,.2f}")
# Output: Revenue: $1,234,567.89百分比与科学计数法
ratio = 0.456
# Percentage formatting
print(f"Completion: {ratio:.1%}")
# Output: Completion: 45.6%
# Scientific notation
big_num = 1234567890
print(f"Scientific: {big_num:.2e}")
# Output: Scientific: 1.23e+09
# Precision with scientific notation
small_num = 0.000000123
print(f"Small: {small_num:.2e}")
# Output: Small: 1.23e-07二进制、八进制与十六进制
number = 255
# Binary
print(f"Binary: {number:b}")
# Output: Binary: 11111111
# Octal
print(f"Octal: {number:o}")
# Output: Octal: 377
# Hexadecimal (lowercase)
print(f"Hex: {number:x}")
# Output: Hex: ff
# Hexadecimal (uppercase)
print(f"Hex: {number:X}")
# Output: Hex: FF
# With prefix
print(f"Binary: {number:#b}, Hex: {number:#x}")
# Output: Binary: 0b11111111, Hex: 0xff字符串对齐与填充
F-strings 提供了强大的对齐能力,可用于生成格式化表格和报告。语法为 {value:fill_char align width},其中 align 可以是 <(左对齐)、>(右对齐)或 ^(居中)。
# Basic alignment
name = "Python"
# Left align (default for strings)
print(f"|{name:<15}|")
# Output: |Python |
# Right align
print(f"|{name:>15}|")
# Output: | Python|
# Center align
print(f"|{name:^15}|")
# Output: | Python |
# Custom fill character
print(f"|{name:*<15}|")
print(f"|{name:*>15}|")
print(f"|{name:*^15}|")
# Output:
# |Python*********|
# |*********Python|
# |****Python*****|对数字来说,默认是右对齐,这非常适合做列对齐:
# Creating aligned tables
products = [
("Apple", 1.50, 10),
("Banana", 0.75, 25),
("Orange", 2.00, 15)
]
print(f"{'Product':<12} {'Price':>8} {'Qty':>6}")
print("-" * 28)
for product, price, qty in products:
print(f"{product:<12} ${price:>7.2f} {qty:>6}")
# Output:
# Product Price Qty
# ----------------------------
# Apple $ 1.50 10
# Banana $ 0.75 25
# Orange $ 2.00 15你还可以把对齐与数字格式化结合起来,输出更专业的效果:
# Financial report formatting
transactions = [
("Sales", 12500.50),
("Returns", -350.25),
("Shipping", -125.00),
("Tax", 1200.00)
]
print(f"{'Category':<15} {'Amount':>12}")
print("=" * 29)
total = 0
for category, amount in transactions:
total += amount
sign = "+" if amount >= 0 else ""
print(f"{category:<15} {sign}{amount:>11,.2f}")
print("=" * 29)
print(f"{'Total':<15} {total:>12,.2f}")
# Output:
# Category Amount
# =============================
# Sales +12,500.50
# Returns -350.25
# Shipping -125.00
# Tax +1,200.00
# =============================
# Total 13,225.25日期与时间格式化
F-strings 能与 datetime 对象无缝配合,让你使用标准的 strftime 指令格式化日期与时间。
from datetime import datetime, timedelta
now = datetime.now()
# Basic date formatting
print(f"Date: {now:%Y-%m-%d}")
# Output: Date: 2026-02-11
# Full datetime
print(f"DateTime: {now:%Y-%m-%d %H:%M:%S}")
# Output: DateTime: 2026-02-11 14:30:45
# Custom formats
print(f"Formatted: {now:%B %d, %Y at %I:%M %p}")
# Output: Formatted: February 11, 2026 at 02:30 PM
# Day of week
print(f"Today is {now:%A}")
# Output: Today is Tuesday
# Combining with other formatting
duration = timedelta(hours=2, minutes=30)
start_time = datetime(2026, 2, 11, 14, 0)
end_time = start_time + duration
print(f"Meeting: {start_time:%I:%M %p} - {end_time:%I:%M %p} ({duration.total_seconds()/3600:.1f} hours)")
# Output: Meeting: 02:00 PM - 04:30 PM (2.5 hours)多行 f-strings
F-strings 支持使用三引号的多行字符串,非常适合生成格式化报告、SQL 查询或结构化文本。
# Multiline f-string
name = "Data Science Team"
members = 12
budget = 150000
report = f"""
Project Report
{'=' * 40}
Team Name: {name}
Members: {members}
Budget: ${budget:,}
Per Member: ${budget/members:,.2f}
"""
print(report)
# Output:
# Project Report
# ========================================
# Team Name: Data Science Team
# Members: 12
# Budget: $150,000
# Per Member: $12,500.00这对生成 SQL 查询或配置文件尤其有用,不过在实际数据库操作中你仍应始终使用参数化查询:
# Template generation (for display, not execution)
table_name = "users"
columns = ["id", "name", "email"]
conditions = {"status": "active", "age": 25}
query = f"""
SELECT {', '.join(columns)}
FROM {table_name}
WHERE status = '{conditions['status']}'
AND age >= {conditions['age']}
ORDER BY name;
"""
print(query)
# Output:
# SELECT id, name, email
# FROM users
# WHERE status = 'active'
# AND age >= 25
# ORDER BY name;使用 = 说明符进行 f-string 调试
Python 3.8 为 f-strings 引入了 = 说明符,可以同时打印表达式与其值。这对调试与日志记录非常有帮助。
# Basic debugging
x = 10
y = 20
print(f"{x=}, {y=}, {x+y=}")
# Output: x=10, y=20, x+y=30
# With formatting
pi = 3.14159
print(f"{pi=:.2f}")
# Output: pi=3.14
# Function calls
def calculate_total(items):
return sum(items)
prices = [10.99, 25.50, 8.75]
print(f"{calculate_total(prices)=:.2f}")
# Output: calculate_total(prices)=45.24
# Complex expressions
data = [1, 2, 3, 4, 5]
print(f"{len(data)=}, {sum(data)=}, {sum(data)/len(data)=:.2f}")
# Output: len(data)=5, sum(data)=15, sum(data)/len(data)=3.00在数据分析流程中,当你需要快速检查中间结果时,这个特性尤其好用:
# Data analysis debugging
dataset = [45, 52, 48, 61, 55, 49, 58]
mean = sum(dataset) / len(dataset)
variance = sum((x - mean) ** 2 for x in dataset) / len(dataset)
std_dev = variance ** 0.5
print(f"""
Statistics:
{len(dataset)=}
{mean=:.2f}
{variance=:.2f}
{std_dev=:.2f}
""")
# Output:
# Statistics:
# len(dataset)=7
# mean=52.57
# variance=28.53
# std_dev=5.34嵌套 f-strings
你可以在 f-string 中嵌套 f-string 来实现动态格式化,但为了可读性应谨慎使用。
# Dynamic precision
value = 3.14159265
precision = 3
result = f"{value:.{precision}f}"
print(result)
# Output: 3.142
# Dynamic width and alignment
text = "Python"
width = 12
align = "^"
formatted = f"{text:{align}{width}}"
print(f"|{formatted}|")
# Output: | Python |
# Complex nesting
values = [1.23456, 7.89012, 3.45678]
decimals = 2
formatted_values = f"Values: {', '.join([f'{v:.{decimals}f}' for v in values])}"
print(formatted_values)
# Output: Values: 1.23, 7.89, 3.46原始 f-strings(Raw f-strings)
原始 f-strings 将 r 与 f 前缀组合起来,让反斜杠按字面量处理,同时仍支持表达式插值。前缀顺序无所谓:rf 和 fr 都可用。
# Regular f-string (backslash escaping active)
path = "Documents"
regular = f"C:\Users\{path}\file.txt" # Would cause issues with \U and \f
# This might not work as expected due to escape sequences
# Raw f-string
raw = rf"C:\Users\{path}\file.txt"
print(raw)
# Output: C:\Users\Documents\file.txt
# Useful for regex patterns
import re
pattern_part = r"\d+"
full_pattern = rf"User ID: {pattern_part}"
print(full_pattern)
# Output: User ID: \d+
# Windows file paths
folder = "Projects"
file = "data.csv"
full_path = rf"C:\Users\Admin\{folder}\{file}"
print(full_path)
# Output: C:\Users\Admin\Projects\data.csv性能对比
F-strings 不仅更易读,也是 Python 中最快的字符串格式化方式。下面是一个对比:
| Method | Syntax Example | Relative Speed | Readability |
|---|---|---|---|
| f-string | f"{name} is {age}" | 1.0x (fastest) | Excellent |
| str.format() | "{} is {}".format(name, age) | 1.5-2x slower | Good |
| % formatting | "%s is %d" % (name, age) | 1.3-1.8x slower | Fair |
| Concatenation | name + " is " + str(age) | 1.2-1.5x slower | Poor |
下面是一个你可以直接运行的实用 benchmark:
import timeit
name = "Alice"
age = 30
# f-string
fstring_time = timeit.timeit(
'f"{name} is {age} years old"',
globals=globals(),
number=1000000
)
# str.format()
format_time = timeit.timeit(
'"{} is {} years old".format(name, age)',
globals=globals(),
number=1000000
)
# % formatting
percent_time = timeit.timeit(
'"%s is %d years old" % (name, age)',
globals=globals(),
number=1000000
)
# Concatenation
concat_time = timeit.timeit(
'name + " is " + str(age) + " years old"',
globals=globals(),
number=1000000
)
print(f"f-string: {fstring_time:.4f}s")
print(f"format(): {format_time:.4f}s ({format_time/fstring_time:.2f}x)")
print(f"% format: {percent_time:.4f}s ({percent_time/fstring_time:.2f}x)")
print(f"concat: {concat_time:.4f}s ({concat_time/fstring_time:.2f}x)")
# Typical output:
# f-string: 0.0523s
# format(): 0.0891s (1.70x)
# % format: 0.0734s (1.40x)
# concat: 0.0612s (1.17x)随着格式化操作变复杂、或在循环中处理大型数据集时,这种性能优势会更明显。
对比:f-strings vs format() vs % Formatting
了解每种方法在何时适用,能帮助你写出更好的 Python 代码:
| Feature | f-string | str.format() | % Formatting |
|---|---|---|---|
| Python Version | 3.6+ | 2.7+ | All versions |
| Readability | Excellent - expressions inline | Good - numbered placeholders | Fair - separate tuple |
| Performance | Fastest | Slower | Moderate |
| Arbitrary Expressions | Yes | Limited | No |
| Positional Args | Direct | Yes | Yes |
| Named Args | Direct | Yes | Yes |
| Reusability | No | Yes | Yes |
| Type Safety | Runtime | Runtime | Runtime |
| Debugging | Excellent (with =) | Fair | Poor |
# Same output, different approaches
name = "Bob"
score = 95.5
rank = 3
# f-string (modern, recommended)
f_result = f"{name} scored {score:.1f} and ranked #{rank}"
# str.format() (good for templates)
format_result = "{} scored {:.1f} and ranked #{}".format(name, score, rank)
# % formatting (legacy)
percent_result = "%s scored %.1f and ranked #%d" % (name, score, rank)
# All produce: "Bob scored 95.5 and ranked #3"
# Where format() excels: reusable templates
template = "Student: {name}, Score: {score:.1f}, Rank: {rank}"
result1 = template.format(name="Alice", score=92.3, rank=5)
result2 = template.format(name="Charlie", score=88.7, rank=8)常见错误与注意事项
转义大括号
如果要在 f-string 中输出字面量大括号,需要把它们写成双大括号:
# Wrong - causes SyntaxError
# result = f"Use {curly braces} in f-strings"
# Correct - double the braces
result = f"Use {{curly braces}} in f-strings"
print(result)
# Output: Use {curly braces} in f-strings
# Mixing escaped and interpolated
value = 42
formatted = f"Set value: {{{value}}}"
print(formatted)
# Output: Set value: {42}表达式中不能使用反斜杠
你不能在 f-string 的表达式部分使用反斜杠:
# Wrong - causes SyntaxError
# result = f"{'\n'.join(items)}"
# Correct - use a variable
newline = '\n'
items = ["apple", "banana", "orange"]
result = f"{newline.join(items)}"
print(result)
# Or use a function/method outside the f-string
result = '\n'.join(items)
final = f"Items:\n{result}"引号匹配
嵌套引号时要格外小心:
# Wrong - quote mismatch
# message = f"{"key": "value"}"
# Correct - use different quote types
message = f'{{"key": "value"}}'
print(message)
# Output: {"key": "value"}
# Or escape inner quotes
message = f"{\"key\": \"value\"}"
print(message)
# Output: "key": "value"在 f-strings 中访问字典
访问字典 key 时,尽量使用与 f-string 不同类型的引号:
data = {"name": "Alice", "score": 95}
# Wrong - quote conflict
# result = f"{data["name"]}"
# Correct - use different quotes
result = f"{data['name']} scored {data['score']}"
print(result)
# Output: Alice scored 95
# Alternative - use get() method
result = f"{data.get('name')} scored {data.get('score')}"真实场景示例
日志消息
F-strings 让日志更易读、更易维护:
import logging
from datetime import datetime
logging.basicConfig(level=logging.INFO)
def process_data(filename, records):
start_time = datetime.now()
logging.info(f"Starting processing: {filename}")
# Simulate processing
success = records * 0.95
failed = records - success
duration = (datetime.now() - start_time).total_seconds()
logging.info(
f"Completed {filename}: "
f"{success:.0f} successful, {failed:.0f} failed "
f"in {duration:.2f}s "
f"({records/duration:.0f} records/sec)"
)
process_data("data.csv", 10000)
# Output: INFO:root:Completed data.csv: 9500 successful, 500 failed in 0.05s (200000 records/sec)文件路径构造
import os
def create_report_path(base_dir, project, date, extension="csv"):
filename = f"{project}_{date:%Y%m%d}_report.{extension}"
return os.path.join(base_dir, filename)
from datetime import date
path = create_report_path(
"/data/reports",
"sales",
date.today()
)
print(path)
# Output: /data/reports/sales_20260211_report.csv使用 PyGWalker 做数据可视化
在数据分析中,f-strings 对于创建动态列名与标签非常关键。PyGWalker 是一个开源 Python 库,可将 dataframe 转换为类似 Tableau 的交互式可视化;配合 f-string 格式化会更得心应手:
import pandas as pd
import pygwalker as pyg
# Create sample data with formatted column names
categories = ["Electronics", "Clothing", "Food"]
months = ["Jan", "Feb", "Mar"]
data = []
for category in categories:
for month in months:
revenue = __import__('random').randint(1000, 5000)
data.append({
f"{month}_Revenue": revenue,
f"{month}_Category": category,
f"{month}_Growth": f"{__import__('random').uniform(-10, 30):.1f}%"
})
df = pd.DataFrame(data)
# Generate dynamic summary
total_revenue = sum([df[f"{m}_Revenue"].sum() for m in months])
summary = f"""
Sales Dashboard Summary
{'=' * 40}
Period: {months[0]} - {months[-1]} 2026
Categories: {len(categories)}
Total Revenue: ${total_revenue:,}
Average per Category: ${total_revenue/len(categories):,.2f}
"""
print(summary)
# PyGWalker can then visualize this formatted data
# pyg.walk(df)报告生成
def generate_performance_report(team_data):
report_lines = [
"Team Performance Report",
"=" * 50,
""
]
total_score = 0
for member in team_data:
name = member["name"]
score = member["score"]
tasks = member["tasks_completed"]
total_score += score
status = "Outstanding" if score >= 90 else "Good" if score >= 75 else "Needs Improvement"
report_lines.append(
f"{name:<20} | Score: {score:>5.1f} | Tasks: {tasks:>3} | {status}"
)
avg_score = total_score / len(team_data)
report_lines.extend([
"",
"=" * 50,
f"Team Average: {avg_score:.1f} | Total Members: {len(team_data)}"
])
return "\n".join(report_lines)
team = [
{"name": "Alice Johnson", "score": 94.5, "tasks_completed": 28},
{"name": "Bob Smith", "score": 87.2, "tasks_completed": 25},
{"name": "Charlie Davis", "score": 78.9, "tasks_completed": 22},
]
print(generate_performance_report(team))
# Output:
# Team Performance Report
# ==================================================
#
# Alice Johnson | Score: 94.5 | Tasks: 28 | Outstanding
# Bob Smith | Score: 87.2 | Tasks: 25 | Good
# Charlie Davis | Score: 78.9 | Tasks: 22 | Good
#
# ==================================================
# Team Average: 86.9 | Total Members: 3API 响应格式化
def format_api_response(endpoint, status_code, response_time, data_size):
status_emoji = "✓" if status_code == 200 else "✗"
message = f"""
API Call Summary:
Endpoint: {endpoint}
Status: {status_code} {status_emoji}
Response Time: {response_time*1000:.0f}ms
Data Size: {data_size:,} bytes ({data_size/1024:.1f} KB)
Throughput: {data_size/response_time/1024:.2f} KB/s
"""
return message
print(format_api_response(
"/api/v2/users",
200,
0.245,
15680
))
# Output:
# API Call Summary:
# Endpoint: /api/v2/users
# Status: 200 ✓
# Response Time: 245ms
# Data Size: 15,680 bytes (15.3 KB)
# Throughput: 62.53 KB/sFAQ
Python f-strings 是什么?我应该在什么时候使用它们?
F-strings(formatted string literals)是 Python 3.6 引入的一种字符串格式化机制,允许你使用大括号在字符串字面量中直接嵌入表达式。只要你需要把变量或表达式插入字符串中,就应该使用 f-strings,因为它在可读性、性能和功能性之间提供了最佳平衡。它非常适合用于日志、报告生成、数据展示,以及任何需要动态生成格式化文本的场景。与 .format() 或 % 格式化等旧方法相比,f-strings 更快,并通过把格式化逻辑与被格式化的值放在一起,让代码更易维护。
如何在 f-strings 中把数字格式化为指定小数位?
在 f-strings 中要控制小数位,可以使用格式说明符 :.Nf,其中 N 是你想要的小数位数。例如 f"{value:.2f}" 会把数字格式化为 2 位小数。你还可以与千分位分隔符组合:f"{value:,.2f}" 会输出类似 "1,234.56" 的效果。百分比使用 % 说明符:f"{ratio:.1%}" 会把 0.456 转成 "45.6%"。科学计数法使用 e 或 E:f"{large_num:.2e}" 会输出类似 "1.23e+09"。
我可以在 f-strings 中使用表达式和函数调用吗?
可以,f-strings 能求值大括号内任何合法的 Python 表达式。这包括算术运算(如 f"{x + y}")、方法调用(如 f"{text.upper()}")、函数调用(如 f"{calculate_total(values):.2f}")、列表推导式、字典访问等。你甚至可以嵌套多个表达式,不过为了可读性,复杂逻辑通常更建议放到 f-string 外部,先赋值给变量再插入。表达式会在运行时求值,结果转成字符串后插入最终输出。
f-strings 里的 = 说明符是什么?它如何帮助调试?
= 说明符是 Python 3.8 引入的调试特性,用于同时输出表达式本身及其值。当你写 f"{variable=}" 时,输出会是 "variable=value",而不只是 "value"。这对调试非常有用,因为你可以在一行里快速检查多个变量而无需重复输入变量名:f"{x=}, {y=}, {x+y=}" 会输出 "x=10, y=20, x+y=30"。它也可以与格式化选项组合:f"{pi=:.2f}" 会输出 "pi=3.14"。在调试数据分析代码或检查中间计算结果时,它能显著节省时间。
如何用 f-strings 创建对齐表格与格式化报告?
要用 f-strings 创建对齐表格,可以在大括号里冒号后使用对齐说明符。语法为 {value:fill_char align width},其中 align 是 <(左对齐)、>(右对齐)或 ^(居中)。例如 f"{text:<15}" 会在 15 字符宽度中左对齐文本,而 f"{number:>10.2f}" 会在 10 字符宽度中右对齐数字并保留 2 位小数。你还可以用自定义填充字符,比如 f"{text:*^20}" 表示用星号填充并居中。生成表格时,通常会结合循环:遍历数据,用一致的列宽格式化每一行,再加上分隔线与表头,就能生成列对齐非常整齐、观感专业的报告。
总结
Python f-strings 已成为现代字符串格式化的标准:它兼具更好的性能与极高的可读性。通过掌握本指南涵盖的技巧——从基础插值到高级格式化、对齐、调试,以及真实场景中的应用——你可以写出更整洁、更快、更易维护的 Python 代码。
它的语法非常直观:在字符串前加 f,在大括号中嵌入表达式,并使用格式说明符控制精度与对齐。无论你是在格式化财务报表、记录应用日志、生成 SQL 查询,还是展示数据分析结果,f-strings 都是最优雅的解决方案。
从今天开始,在你的代码库中用 f-strings 替换旧的格式化方式。未来的你和你的队友都会更喜欢这种更清晰的写法,而你的应用也会从性能提升中受益。当你使用 PyGWalker 等数据分析工具或构建复杂的报表系统时,f-strings 会成为你 Python 工具箱里不可或缺的一部分。