用 string.Template 生成文本:占位符与缺失参数
1. 为什么使用 string.Template
Python 标准库的 string.Template 提供了一种较简单的文本替换机制。与 str.format() 或 f-string 相比,它只处理命名占位符,不支持属性访问、索引和格式化表达式,因此适合通知模板、配置片段、命令说明等不需要复杂逻辑的文本。
使用前需要导入:
from string import Template
2. 占位符的基本形式
默认情况下,占位符有两种写法:
$name:直接使用标识符;${name}:使用花括号明确占位符边界。
下面是一个可直接运行的例子:
from string import Template
text = Template("用户 $user 有 ${count} 条新消息。")
result = text.substitute(user="Alice", count=3)
print(result)
输出为:
用户 Alice 有 3 条新消息。
传入的整数 3 会在替换时转换成字符串。默认占位符名称应采用由字母或下划线开头、后接字母、数字或下划线的形式。
花括号在占位符紧邻其他字符时尤其重要:
from string import Template
name = "report"
print(Template("文件:${name}_final.txt").substitute(name=name))
输出为:
文件:report_final.txt
如果写成 $name_final,解析器会把 name_final 视为完整的占位符,而不是把 $name 与 _final 分开。
3. 输出字面量美元符号
两个连续的美元符号 $$ 表示一个普通的 $:
from string import Template
price = Template("商品:$item,价格:$$$amount")
print(price.substitute(item="键盘", amount="99.00"))
输出为:
商品:键盘,价格:$99.00
其中 $$ 生成字面量美元符号,$amount 则执行参数替换。
4. substitute():缺失参数立即报错
substitute() 要求所有占位符都能找到对应值。参数缺失时会抛出 KeyError:
from string import Template
message = Template("任务 $task 的状态是 $status")
try:
print(message.substitute(task="备份"))
except KeyError as exc:
print(f"缺少参数:{exc.args[0]}")
输出为:
缺少参数:status
这种方式适合严格生成:例如邮件发送前、文件写入前或配置导出前,程序必须确认模板参数完整。捕获异常时,exc.args[0] 是缺失的占位符名称。
参数也可以通过映射传入:
from string import Template
values = {"project": "demo", "version": "1.0"}
t = Template("项目:$project,版本:$version")
print(t.substitute(values))
输出为:
项目:demo,版本:1.0
5. safe_substitute():保留缺失占位符
如果希望先生成部分文本,再由后续步骤补充数据,可以使用 safe_substitute()。缺失的占位符不会引发 KeyError,而是原样保留:
from string import Template
message = Template("收件人:$recipient\n主题:$subject\n编号:$ticket")
result = message.safe_substitute(
recipient="张三",
subject="问题已受理"
)
print(result)
输出为:
收件人:张三
主题:问题已受理
编号:$ticket
这适合分阶段填充、模板预览和允许部分字段为空缺的场景。但它也可能掩盖变量名拼写错误。例如模板误写 $stauts 时,该内容会被保留,而程序不会立即失败。因此,对最终必须完整的文本,通常应优先使用 substitute()。
6. 在替换前检查参数
Template 提供 get_identifiers(),可以获取模板中的有效占位符名称;is_valid() 可以检查模板语法是否有效:
from string import Template
source = "欢迎 $user,订单号为 ${order_id},金额 $$20"
t = Template(source)
provided = {"user": "李明"}
required = set(t.get_identifiers())
missing = required - provided.keys()
print("模板有效:", t.is_valid())
print("缺失参数:", sorted(missing))
输出为:
模板有效: True
缺失参数: ['order_id']
这两个方法适合在真正替换前给出更友好的校验信息。它们属于较新的稳定接口;如果需要兼容不提供这些方法的旧版 Python,可直接调用 substitute() 并处理 KeyError 和 ValueError。
7. 边界条件与适用范围
单独出现的 $、未闭合的 ${name 或其他不符合规则的占位符可能导致 substitute() 抛出 ValueError。模板来自文件或用户输入时,应同时处理语法错误和缺失参数:
from string import Template
try:
output = Template("结果:$value").substitute({})
except KeyError as exc:
output = f"参数缺失:{exc.args[0]}"
except ValueError as exc:
output = f"模板语法错误:{exc}"
print(output)
Template 不会执行占位符中的 Python 表达式,也不提供循环、条件、数字格式化或日期格式化。需要这些能力时,应先在 Python 代码中完成计算,再把最终字符串交给模板。它适合简单、可读、低逻辑量的文本生成,不应被当作完整模板引擎或数据校验工具。
参考资料
- Python 标准库文档:《string — Common string operations》→
Template strings - Python 标准库文档:
string.Template→substitute、safe_substitute、is_valid、get_identifiers
本文由 AI 辅助编写,示例需要读者在目标 Python 环境中自行验证。
- 点赞
- 收藏
- 关注作者
评论(0)