用 string.Template 生成文本:占位符与缺失参数

举报
yd_269910332 发表于 2026/11/03 17:25:33 2026/11/03
【摘要】 介绍 Python 标准库 string.Template 的占位符语法、转义方式,以及 substitute 与 safe_substitute 面对缺失参数时的不同行为,并说明边界条件和适用场景。

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 环境中自行验证。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。