日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Python 3.14 t-string 要来了,它与 f-string 有何不同?

發布時間:2025/5/22 编程问答 31 如意码农
生活随笔 收集整理的這篇文章主要介紹了 Python 3.14 t-string 要来了,它与 f-string 有何不同? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python 最近出了個大新聞:PEP-750 t-string 語法被正式采納了!

這意味著 Python 將在今年 10 月發布的 3.14 版本中引入一種新的字符串前綴 t,稱為模板字符串(Template Strings),即 t-string。

這是繼 f-string 之后,字符串處理能力的重大升級,旨在提供更安全、更靈活的字符串插值處理機制。

t-string 的基本語法與 f-string 非常相似,但得到的結果卻大為不同:

name = "World"

# f-string 語法
formatted = f"Hello {name}!"
print(type(formatted)) # 輸出:<class 'str'>
print(formatted) # 輸出:Hello World! # t-string 語法
templated = t"Hello {name}!"
print(type(templated)) # 輸出:<class 'string.templatelib.Template'>
print(templated.strings) # 輸出:('Hello ', '')
print(templated.interpolations[0].value) # 輸出:World
print("".join(
item if isinstance(item, str) else str(item.value)
for item in templated
)) # 輸出:Hello World!

如上所述,t-string 與 f-string 不同的是,它不會立即得到普通字符串,而是返回一個新的類型 Template(來自 Python 3.14 新增的標準庫模塊 string.templatelib)。

這個類型不能直接作為普通字符串輸出,但它提供了對字符串和其內部插值表達式的結構化訪問,使得開發者能夠在字符串組合插入值前添加攔截和轉換。

一句話總結 t-string 的核心特點就是延遲渲染

為什么要設計 t-string?

f-string 因其簡潔易用而廣受歡迎,但它也存在一些無法忽視的局限性:

  1. 安全隱患:當直接將用戶輸入嵌入到 SQL 查詢、HTML 內容或系統命令中時,f-string 可能導致注入攻擊
  2. 缺乏轉換能力:f-string 沒有提供在字符串組合前攔截和轉換插入值的機制
  3. 靈活性不足:對于復雜的字符串處理任務,f-string 的能力有限

提升字符串處理的安全性

不謹慎使用 f-string,可能導致安全漏洞:

# 使用 f-string 的不安全示例(SQL 注入風險)
sql_query = f"SELECT * FROM users WHERE name = '{user_input}'" # 使用 f-string 的不安全示例(XSS 風險)
html_content = f"<div>{user_input}</div>"

而 t-string 允許開發者在字符串組合前對插值進行適當處理:

# 使用 t-string 的安全示例
evil = "<script>alert('evil')</script>"
template = t"<p>{evil}</p>"
# 可以定義處理函數來轉義內容
assert html(template) == "<p>&lt;script&gt;alert('evil')&lt;/script&gt;</p>"

增強字符串處理的靈活性

t-string 最大的優勢在于它提供了統一的字符串處理機制,讓開發者可以根據實際需求實現各種自定義渲染邏輯。這種設計避免了為每種場景創建專門語法的復雜性,同時保持了 Python 簡潔統一的風格。

以下示例展示了如何基于同一個 t-string 模板,利用不同的渲染器輸出不同的格式:

from string.templatelib import Template, Interpolation

data = {"name": "Python貓", "age": 18}
template = t"用戶 {data['name']} 的年齡是 {data['age']}" def standard_renderer(template: Template) -> str:
"""標準文本渲染"""
return "".join(
item if isinstance(item, str) else str(item.value)
for item in template
) def json_renderer(template: Template) -> str:
"""JSON格式渲染"""
import json, re
values = {}
for item in template:
if not isinstance(item, str):
# 使用正則表達式從表達式中提取鍵名
# 匹配 data['name'] 或 data["name"] 模式中的name
match = re.search(r"\['([^']+)'\]|\[\"([^\"]+)\"\]", item.expression)
if match:
# 獲取匹配的第一個分組
key = match.group(1) if match.group(1) else match.group(2)
values[key] = item.value
return json.dumps(values, ensure_ascii=False) def xml_renderer(template: Template) -> str:
"""XML格式渲染"""
parts = ["<data>"]
for item in template:
if not isinstance(item, str) and hasattr(item, "expression"):
name = item.expression.split("'")[1] if "'" in item.expression else item.expression
parts.append(f" <{name}>{item.value}</{name}>")
parts.append("</data>")
return "\n".join(parts) # 同一個模板,不同的輸出格式
print(standard_renderer(template)) # 輸出: 用戶 Python貓 的年齡是 18
print(json_renderer(template)) # 輸出: {"name": "Python貓", "age": 18}
print(xml_renderer(template)) # 輸出: <data>\n <name>Python貓</name>\n <age>18</age>\n</data>

這種靈活性是 f-string 所不具備的,對于構建各種 DSL(領域特定語言)、模板引擎或格式化系統非常有價值。

Template 類的結構

t-string 求值后的 Template 類具有以下主要屬性和方法:

class Template:
strings: tuple[str, ...]
"""
模板中字符串部分的非空元組。
包含 N+1 個元素,其中 N 是模板中插值表達式的數量。
""" interpolations: tuple[Interpolation, ...]
"""
模板中插值部分的元組。
如果沒有插值表達式,這將是一個空元組。
""" def __new__(cls, *args: str | Interpolation):
"""
創建一個新的 Template 實例。
參數可以按任意順序提供。
"""
... @property
def values(self) -> tuple[object, ...]:
"""
返回模板中每個 Interpolation 的 `value` 屬性組成的元組。
如果沒有插值表達式,這將是一個空元組。
"""
... def __iter__(self) -> Iterator[str | Interpolation]:
"""
迭代模板中的字符串部分和插值表達式。
這些可能以任意順序出現。不包含空字符串。
"""
...

這種結構使開發者能夠:

  • 訪問原始字符串片段(strings

  • 訪問插值表達式及其計算結果(interpolations

  • 直接獲取所有插值的值(values

  • 按順序迭代模板的所有組成部分

注:__iter__ 函數注釋說出現順序不固定,但 PEP 文檔中它的具體實現卻是按序的,我認為是注釋有誤。

t-string 與 f-string 的異同點

相似之處

  1. 基本語法:二者都使用花括號 {} 作為插值表達式的分隔符
  2. 表達式求值:都支持在花括號中放置任意 Python 表達式
  3. 格式說明符:都支持格式說明符(如 .2f)和轉換說明符(如 !r
  4. 引號支持:都支持所有有效的引號標記('"'''""")
  5. 大小寫不敏感前綴tT 都是有效的,就像 fF

不同之處

  1. 返回類型:f-string 直接返回 str 類型,而 t-string 返回 Template 類型
  2. 求值時機:f-string 在定義時立即求值,t-string 提供延遲求值能力
  3. 結構訪問:t-string 允許訪問原始模板的結構(字符串部分和插值部分)
  4. 處理模型:f-string 是"即時完成"模型,t-string 是"預處理+轉換"模型

t-string 的應用場景

1. 安全的 HTML 模板

使用 t-string 可以創建出自動轉義用戶輸入的 HTML 模板:

def html(template: Template) -> str:
parts = []
for item in template:
if isinstance(item, str):
parts.append(item)
else: # Interpolation
parts.append(html_escape(item.value))
return "".join(parts) user_input = "<script>alert('XSS')</script>"
safe_html = html(t"<div>{user_input}</div>")
# 輸出: <div>&lt;script&gt;alert('XSS')&lt;/script&gt;</div>

2. 安全的 SQL 查詢構建

t-string 可以構建防注入的 SQL 查詢:

def safe_sql(template: Template) -> str:
parts = []
params = [] for item in template:
if isinstance(item, str):
parts.append(item)
else:
parts.append("?")
params.append(item.value) return "".join(parts), params user_id = "user' OR 1=1--"
query, params = safe_sql(t"SELECT * FROM users WHERE id = {user_id}")
# query: "SELECT * FROM users WHERE id = ?"
# params: ["user' OR 1=1--"]

3. 結構化日志

使用 t-string 可以實現優雅的結構化日志記錄:

import json
import logging
from string.templatelib import Template, Interpolation class TemplateMessage:
def __init__(self, template: Template) -> None:
self.template = template @property
def message(self) -> str:
# 格式化為可讀消息
return f(self.template) # 使用自定義 f() 函數 @property
def values(self) -> dict:
# 提取結構化數據
return {
item.expression: item.value
for item in self.template.interpolations
} def __str__(self) -> str:
return f"{self.message} >>> {json.dumps(self.values)}" action, amount, item = "traded", 42, "shrubs"
logging.info(TemplateMessage(t"User {action}: {amount:.2f} {item}"))
# 輸出: User traded: 42.00 shrubs >>> {"action": "traded", "amount": 42, "item": "shrubs"}

4. 安全的子進程調用

PEP-787 專門針對 t-string 在子進程調用中的場景作了擴展,使 subprocess 模塊能原生支持 t-string:

# 不安全的 f-string 用法
subprocess.run(f"echo {message_from_user}", shell=True) # 命令注入風險 # 安全的 t-string 用法
subprocess.run(t"echo {message_from_user}") # 自動進行適當的命令轉義

這種方式既保留了字符串命令的可讀性,又避免了安全風險。

t-string 的進階用法

1. 自定義多功能模板渲染器

t-string 的真正威力在于可以自定義渲染器模板:

from string.templatelib import Template, Interpolation
import html def smart_renderer(template: Template, context="text") -> str:
"""上下文感知的渲染器
根據context參數自動決定如何處理每個插值:
- "text": 普通文本模式,直接轉為字符串
- "html": HTML模式,自動轉義HTML特殊字符,防止XSS
- "sql": SQL模式,自動轉義SQL特殊字符,防止注入
"""
parts = [] for item in template:
if isinstance(item, str):
parts.append(item)
else: # Interpolation
value = item.value
expression = item.expression # 基于值類型和上下文進行智能處理
if context == "html":
# HTML模式:自動轉義HTML特殊字符
parts.append(html.escape(str(value)))
elif context == "sql":
# SQL模式:防止SQL注入
if isinstance(value, str):
# 將1個單引號轉義成2個
escaped_value = value.replace("'", "''")
parts.append(f"'{escaped_value}'")
elif value is None:
parts.append("NULL")
else:
parts.append(str(value))
else:
parts.append(str(value)) return "".join(parts) # 同一個模板在不同上下文中的自動適配渲染
user_input = "<script>alert('evil')</script>"
template = t"用戶輸入: {user_input}"
print(smart_renderer(template, context="html")) # 輸出: 用戶輸入: &lt;script&gt;alert('evil')&lt;/script&gt; # SQL注入防護示例
user_id = "1'; DROP TABLE users; --"
sql_template = t"SELECT * FROM users WHERE id = {user_id}"
print(smart_renderer(sql_template, context="sql")) # 輸出: SELECT * FROM users WHERE id = '1''; DROP TABLE users; --' # f-string 對于SQL注入,必須先處理值,再放入f-string
escaped_id = user_id.replace("'", "''")
sql_safe_id = f"'{escaped_id}'"
print(f"SQL查詢(f-string): SELECT * FROM users WHERE id = {sql_safe_id}")

2. 結構化嵌套模板處理

t-string 和 f-string 在嵌套使用時有本質區別:

# f-string的嵌套:內部表達式立即求值,信息丟失
value = "world"
inner_f = f"inner {value}"
outer_f = f"outer {inner_f}"
print(outer_f) # 輸出: outer inner world
print(type(outer_f)) # <class 'str'> - 只是普通字符串 # t-string的嵌套:保留完整結構信息
inner_t = t"inner {value}"
outer_t = t"outer {inner_t}"
print(type(outer_t)) # <class 'string.templatelib.Template'>
print(type(outer_t.interpolations[0].value)) # 也是Template對象! # 可以訪問和處理任意深度的嵌套結構
user = {"name": "Alice", "age": 30}
message = t"用戶{user['name']}信息: {t'年齡:{user['age']}'}"
inner_template = message.interpolations[1].value
print(inner_template.strings) # 輸出: ('年齡:', '')
print(inner_template.interpolations[0].value) # 輸出: 30

這種結構化處理能力使 t-string 特別適合構建復雜的模板系統,可以按需延遲或自定義渲染過程的所有部分。

3. 延遲求值與異步處理

t-string 的結構特性使得它支持延遲求值和異步處理。以下是異步模板渲染示例:

import asyncio

# 模擬異步數據獲取
async def fetch_data(key: str) -> str:
await asyncio.sleep(0.1) # 模擬網絡延遲
return f"獲取的{key}數據" async def render_async(template):
tasks = {}
# 并行啟動所有異步查詢
for item in template.interpolations:
tasks[item.expression] = asyncio.create_task(
fetch_data(item.expression)
) # 等待所有查詢完成
for expr, task in tasks.items():
tasks[expr] = await task # 組裝結果
result = []
for item in template:
if isinstance(item, str):
result.append(item)
else:
result.append(tasks[item.expression]) return "".join(result) async def main():
template = t"用戶: {user}, 年齡: {age}"
result = await render_async(template)
print(result) # asyncio.run(main())

這種模式的關鍵優勢:

  • 結構保留: 可以獲取完整表達式信息
  • 并行獲取: 同時處理多個異步任務
  • 延遲組合: 等所有數據就緒再拼接

總結

Python 的 t-string 語法是對字符串處理能力的重要擴展,它在保持與 f-string 語法相似性的同時,提供了更靈活、更安全的字符串插值處理機制。通過將字符串模板結構化為 Template 對象,開發者可以在字符串組合前對插值進行攔截和轉換,從而避免常見的安全問題,并支持更多高級用例。

它就像是數據與視圖的分離模式,f-string 是直接渲染的視圖,而 t-string則保留了數據模型,允許你在最終呈現前執行各種轉換規則和驗證。

t-string 的設計理念體現了功能性與安全性的平衡,雖然它比 f-string 更復雜,但這種復雜性帶來了更高級的可組合性和更強的安全保障。

它遵循了 Python 的"顯式優于隱式"原則,通過明確分離模板結構和渲染過程,讓字符串處理的每個步驟都清晰可見。

t-string 并不是一種替換 f-string 的語法,f-string 的簡單易用性依然有其重要價值。

那么,在 Python 3.14 版本后,兩個字符串插值方法該如何選擇呢?

一句話總結:當只需簡單地格式化字符串時,使用 f-string 更直接高效;而當處理不受信任的輸入、需要自定義渲染邏輯、構建復雜模板系統或進行異步處理時,應選擇功能更強大的 t-string。

參考資料

  1. PEP 750 – Template Strings
  2. PEP 787 – Safer subprocess usage using t-strings
  3. Template strings accepted for Python 3.14

Python 潮流周刊第3季總結,附電子書下載:https://pythoncat.top/posts/2025-04-20-sweekly

Python 潮流周刊第二季完結(31~60):https://pythoncat.top/posts/2025-04-20-iweekly

Python 潮流周刊第 2 季完結了,分享幾項總結:https://pythoncat.top/posts/2024-07-14-iweekly

Python 潮流周刊第2季(31~60)-純鏈接版:https://pythoncat.top/posts/2025-04-19-sweekly

Python 潮流周刊第一季精華合集(1~30):https://pythoncat.top/posts/2023-12-11-weekly

萬字濃縮版,Python 潮流周刊第 1 季的 800 個鏈接!:https://xiaobot.net/post/78c3d645-86fa-4bd8-8eac-46fb192a339e

微信關注 Python貓:https://img02.100why.cn/HCT20250522/python_cat.jpg

總結

以上是生活随笔為你收集整理的Python 3.14 t-string 要来了,它与 f-string 有何不同?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: jizz教师| 黄色美女免费网站 | 天天射天天干天天操 | 制服av在线| 女人喂男人奶水做爰视频 | 四虎国产成人精品免费一女五男 | 美国免费黄色片 | 精品动漫av| 欲色av | 欧美亚洲三级 | 亚洲老老头同性老头交j | 色哟哟无码精品一区二区三区 | 国产第一亚洲 | 国产在线精品一区二区 | 91国产在线看 | 欧美综合色区 | 亚洲国产精品久久久久久久 | 午夜精品久久久久久久久久久 | 97caop| 日韩激情视频在线 | 亚洲av电影一区二区 | 亚洲女成人图区 | 日韩av少妇| 在线成人免费电影 | 中文字幕精品一区 | 欧美生活一级片 | 中文字幕有码在线视频 | 农村妇女毛片 | 无码精品人妻一区二区三区漫画 | 亚洲一区二区三区蜜桃 | 国产精品一区二区三区免费在线观看 | 精品久久久噜噜噜久久久 | a国产| 亚洲婷婷网 | 姐姐你真棒插曲快来救救我电影 | 日韩专区第一页 | 欧美资源网 | 8x8x最新网址 | 日韩亚射吧 | 午夜久久精品 | 美女在线播放 | 永久免费在线播放 | 欧美a网站 | 日韩草逼| 国产伦精品一区二区三区妓女下载 | 青青成人在线 | 欧美与黑人午夜性猛交久久久 | 久久久久成人精品无码中文字幕 | 伊人亚洲天堂 | 成人国产精品免费观看视频 | 欧美激情精品 | 精品一区二区三区视频在线观看 | 免费色av | 色诱视频在线观看 | 在线欧美成人 | 亚洲欧美成人一区二区 | 在线综合色 | 久久伊人网站 | 欧美国产视频一区 | 国产区第一页 | 日本骚少妇 | 狠狠爱综合网 | 成人黄网免费观看视频 | 香蕉视频国产 | 日韩一级性 | 色欲无码人妻久久精品 | 中文字幕一区在线播放 | 欧美熟妇激情一区二区三区 | 日韩不卡av | 一区二区三区高清 | 久久99久久99精品 | 麻豆视频一区二区 | 奇米网久久 | 国产人妻精品一区二区三区不卡 | 欧美xxxxav | 午夜免费大片 | 撸啊撸av | 欧美精品1区2区3区 精品成人一区 | 国产另类视频 | 国产高潮久久久 | 蜜桃视频中文字幕 | 骚婷婷 | 国产一区二区三区视频在线观看 | 最近中文字幕mv免费高清在线 | 久久中出 | 日本国产一区二区三区 | 中文字字幕在线中文乱码电影 | 日韩五码在线 | 免费在线观看www | 日韩欧美综合 | 成人在线一区二区三区 | 亚洲の无码国产の无码步美 | 狠狠天堂| 色网网站 | 色戒av | 亚洲欧美自拍另类 | 日韩av手机在线观看 | 成人网在线观看 | 亚洲综合无码一区二区 |