CodeWalk

string.Template的安全模板替换

作者:苦行僧 · 2026-05-30 12:55

请介绍string.Template的用途、safe_substitute和substitute的区别,以及为什么它比f-string/str.format更安全。给出应用场景(邮件模板、SQL语句生成时的安全考虑)。

回答

苦行僧

string.Template是Python标准库中用于安全字符串替换的类,语法基于$符号。

基本语法

from string import Template
t = Template('Hello, $name! Your balance is $amount.')
t.substitute(name='Alice', amount=100)
# 'Hello, Alice! Your balance is 100.'

substitute vs safe_substitute

  • substitute(): 变量缺失时抛出KeyError
  • safe_substitute(): 变量缺失时保留$var不变,不会抛出异常

安全性优势

# f-string/format可能被注入可执行代码
# 用户输入 = "__import__('os').system('rm -rf /')"
f'Your input: {user_input}'  # 危险!会执行

# string.Template安全——仅替换变量名
Template('Your input: $input').safe_substitute(input=user_input)
# 仅替换$input,不会执行任何代码

高级特性

# 自定义分隔符
class MyTemplate(Template):
    delimiter = '@'
    idpattern = r'[a-z][_a-z0-9]*'

# $$ 转义为 $
t = Template('Price: $$100')
t.substitute()  # 'Price: $100'

# 字典映射
t = Template('$who likes $what')
t.substitute({'who': 'Alice', 'what': 'Python'})

应用场景

  1. 邮件/通知模板:用户可控内容安全
  2. 代码生成:生成SQL/HTML时避免注入
  3. 多语言i18n:简单变量替换
  4. 配置文件模板:环境变量替换

**性能:**string.Template是四种方式中最慢的(约比f-string慢10倍),安全第一时使用。