Python3.14新特性Template Strings(t-string)使用示例
Python中可能已经有很多类似模板字符串的东西,但都和 PEP 750 中的 string.templatelib 不一样
比如:string.Template 、string.Formatter/str.format() 、 f-string 和%
这种上古写法。
在 PEP 750中提到的Motivation中指出f-string的语法虽然方便,但经常会因为操作者处理SQL语句或者HTML文档时直接拼接导致出现安全漏洞。
(实话说这里确实挺抽象的。f-string没有任何问题,问题出在程序员没有对输入的内容进行预处理而直接拼接。)
>>> name = 'duzhuo'
>>> template = t'Hello,{name}'
>>> template
Template(strings=('Hello,', ''), interpolations=(Interpolation('duzhuo', 'name', None, ''),))
SQL参数化查询
from string.templatelib import Template, Interpolation
import sqlite3
def run_query(db, template: Template):
parts = []
params = []
for i in template:
if type(i) is str:
parts.append(i)
if type(i) is Interpolation:
parts.append("?")
# i.value是一个tuple
params.append(i.value)
query_string = "".join(parts)
print(query_string)
# SELECT * FROM products
# WHERE is_available = ? AND category = ?
return db.execute("".join(parts), params)
def main():
db = sqlite3.connect("./test.db")
is_available = 1
category = "Home"
template = t"""
SELECT * FROM products
WHERE is_available = {is_available} AND category = {category}
"""
print(list(run_query(db, template)))
if __name__ == "__main__":
main()
HTML转义
from html import escape
from string.templatelib import Template, Interpolation
def safe_html(template: Template) -> str:
parts = []
for i in template:
if type(i) is str:
parts.append(i)
if type(i) is Interpolation:
parts.append(escape(i.value))
return "".join(parts)
def main():
user_input1 = "duzhuo"
user_input2 = '<script>alert("XSS Attacking")</script>'
html_template = t"""
<div>
My name is <strong>{user_input1}</strong>, Here is my Message: {user_input2}
</div>
"""
print(safe_html(html_template))
#
# <div>
# My name is <strong>duzhuo</strong>, Here is my Message: <script>alert("XSS Attacking")</script>
# </div>
if __name__ == "__main__":
main()