<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Python 3.14 t-string 要來了,它與 f-string 有何不同?

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

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

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

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

      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 不同的是,它不會(huì)立即得到普通字符串,而是返回一個(gè)新的類型 Template(來自 Python 3.14 新增的標(biāo)準(zhǔn)庫(kù)模塊 string.templatelib)。

      這個(gè)類型不能直接作為普通字符串輸出,但它提供了對(duì)字符串和其內(nèi)部插值表達(dá)式的結(jié)構(gòu)化訪問,使得開發(fā)者能夠在字符串組合插入值前添加攔截和轉(zhuǎn)換。

      一句話總結(jié) t-string 的核心特點(diǎn)就是延遲渲染

      為什么要設(shè)計(jì) t-string?

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

      1. 安全隱患:當(dāng)直接將用戶輸入嵌入到 SQL 查詢、HTML 內(nèi)容或系統(tǒng)命令中時(shí),f-string 可能導(dǎo)致注入攻擊
      2. 缺乏轉(zhuǎn)換能力:f-string 沒有提供在字符串組合前攔截和轉(zhuǎn)換插入值的機(jī)制
      3. 靈活性不足:對(duì)于復(fù)雜的字符串處理任務(wù),f-string 的能力有限

      提升字符串處理的安全性

      不謹(jǐn)慎使用 f-string,可能導(dǎo)致安全漏洞:

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

      而 t-string 允許開發(fā)者在字符串組合前對(duì)插值進(jìn)行適當(dāng)處理:

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

      增強(qiáng)字符串處理的靈活性

      t-string 最大的優(yōu)勢(shì)在于它提供了統(tǒng)一的字符串處理機(jī)制,讓開發(fā)者可以根據(jù)實(shí)際需求實(shí)現(xiàn)各種自定義渲染邏輯。這種設(shè)計(jì)避免了為每種場(chǎng)景創(chuàng)建專門語法的復(fù)雜性,同時(shí)保持了 Python 簡(jiǎn)潔統(tǒng)一的風(fēng)格。

      以下示例展示了如何基于同一個(gè) 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:
          """標(biāo)準(zhǔn)文本渲染"""
          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):
                  # 使用正則表達(dá)式從表達(dá)式中提取鍵名
                  # 匹配 data['name'] 或 data["name"] 模式中的name
                  match = re.search(r"\['([^']+)'\]|\[\"([^\"]+)\"\]", item.expression)
                  if match:
                      # 獲取匹配的第一個(gè)分組
                      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)
      
      # 同一個(gè)模板,不同的輸出格式
      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 所不具備的,對(duì)于構(gòu)建各種 DSL(領(lǐng)域特定語言)、模板引擎或格式化系統(tǒng)非常有價(jià)值。

      Template 類的結(jié)構(gòu)

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

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

      這種結(jié)構(gòu)使開發(fā)者能夠:

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

      • 訪問插值表達(dá)式及其計(jì)算結(jié)果(interpolations

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

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

      注:__iter__ 函數(shù)注釋說出現(xiàn)順序不固定,但 PEP 文檔中它的具體實(shí)現(xiàn)卻是按序的,我認(rèn)為是注釋有誤。

      t-string 與 f-string 的異同點(diǎn)

      相似之處

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

      不同之處

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

      t-string 的應(yīng)用場(chǎng)景

      1. 安全的 HTML 模板

      使用 t-string 可以創(chuàng)建出自動(dòng)轉(zhuǎn)義用戶輸入的 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 查詢構(gòu)建

      t-string 可以構(gòu)建防注入的 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. 結(jié)構(gòu)化日志

      使用 t-string 可以實(shí)現(xiàn)優(yōu)雅的結(jié)構(gòu)化日志記錄:

      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() 函數(shù)
          
          @property
          def values(self) -> dict:
              # 提取結(jié)構(gòu)化數(shù)據(jù)
              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. 安全的子進(jìn)程調(diào)用

      PEP-787 專門針對(duì) t-string 在子進(jìn)程調(diào)用中的場(chǎng)景作了擴(kuò)展,使 subprocess 模塊能原生支持 t-string:

      # 不安全的 f-string 用法
      subprocess.run(f"echo {message_from_user}", shell=True)  # 命令注入風(fēng)險(xiǎn)
      
      # 安全的 t-string 用法
      subprocess.run(t"echo {message_from_user}")  # 自動(dòng)進(jìn)行適當(dāng)?shù)拿钷D(zhuǎn)義
      

      這種方式既保留了字符串命令的可讀性,又避免了安全風(fēng)險(xiǎn)。

      t-string 的進(jìn)階用法

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

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

      from string.templatelib import Template, Interpolation
      import html
      
      def smart_renderer(template: Template, context="text") -> str:
          """上下文感知的渲染器
          根據(jù)context參數(shù)自動(dòng)決定如何處理每個(gè)插值:
          - "text": 普通文本模式,直接轉(zhuǎn)為字符串
          - "html": HTML模式,自動(dòng)轉(zhuǎn)義HTML特殊字符,防止XSS
          - "sql": SQL模式,自動(dòng)轉(zhuǎn)義SQL特殊字符,防止注入
          """
          parts = []
          
          for item in template:
              if isinstance(item, str):
                  parts.append(item)
              else:  # Interpolation
                  value = item.value
                  expression = item.expression
                  
                  # 基于值類型和上下文進(jìn)行智能處理
                  if context == "html":
                      # HTML模式:自動(dòng)轉(zhuǎn)義HTML特殊字符
                      parts.append(html.escape(str(value)))
                  elif context == "sql":
                      # SQL模式:防止SQL注入
                      if isinstance(value, str):
                          # 將1個(gè)單引號(hào)轉(zhuǎn)義成2個(gè)
                          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)
      
      # 同一個(gè)模板在不同上下文中的自動(dòng)適配渲染
      user_input = "<script>alert('evil')</script>"
      template = t"用戶輸入: {user_input}"
      print(smart_renderer(template, context="html")) # 輸出: 用戶輸入: &lt;script&gt;alert(&#x27;evil&#x27;)&lt;/script&gt;
      
      # SQL注入防護(hù)示例
      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 對(duì)于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. 結(jié)構(gòu)化嵌套模板處理

      t-string 和 f-string 在嵌套使用時(shí)有本質(zhì)區(qū)別:

      # f-string的嵌套:內(nèi)部表達(dá)式立即求值,信息丟失
      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的嵌套:保留完整結(jié)構(gòu)信息
      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對(duì)象!
      
      # 可以訪問和處理任意深度的嵌套結(jié)構(gòu)
      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
      

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

      3. 延遲求值與異步處理

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

      import asyncio
      
      # 模擬異步數(shù)據(jù)獲取
      async def fetch_data(key: str) -> str:
          await asyncio.sleep(0.1)  # 模擬網(wǎng)絡(luò)延遲
          return f"獲取的{key}數(shù)據(jù)"
      
      async def render_async(template):
          tasks = {}
          # 并行啟動(dòng)所有異步查詢
          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
          
          # 組裝結(jié)果
          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())
      

      這種模式的關(guān)鍵優(yōu)勢(shì):

      • 結(jié)構(gòu)保留: 可以獲取完整表達(dá)式信息
      • 并行獲取: 同時(shí)處理多個(gè)異步任務(wù)
      • 延遲組合: 等所有數(shù)據(jù)就緒再拼接

      總結(jié)

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

      它就像是數(shù)據(jù)與視圖的分離模式,f-string 是直接渲染的視圖,而 t-string則保留了數(shù)據(jù)模型,允許你在最終呈現(xiàn)前執(zhí)行各種轉(zhuǎn)換規(guī)則和驗(yàn)證。

      t-string 的設(shè)計(jì)理念體現(xiàn)了功能性與安全性的平衡,雖然它比 f-string 更復(fù)雜,但這種復(fù)雜性帶來了更高級(jí)的可組合性和更強(qiáng)的安全保障。

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

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

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

      一句話總結(jié):當(dāng)只需簡(jiǎn)單地格式化字符串時(shí),使用 f-string 更直接高效;而當(dāng)處理不受信任的輸入、需要自定義渲染邏輯、構(gòu)建復(fù)雜模板系統(tǒng)或進(jìn)行異步處理時(shí),應(yīng)選擇功能更強(qiáng)大的 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季總結(jié),附電子書下載:https://pythoncat.top/posts/2025-04-20-sweekly

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

      Python 潮流周刊第 2 季完結(jié)了,分享幾項(xiàng)總結(jié):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 個(gè)鏈接!:https://xiaobot.net/post/78c3d645-86fa-4bd8-8eac-46fb192a339e

      微信關(guān)注 Python貓https://img.pythoncat.top/python_cat.jpg

      posted @ 2025-04-28 20:28  豌豆花下貓  閱讀(2006)  評(píng)論(2)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产精品自拍一二三四区| 欧洲精品色在线观看| 国产精品欧美一区二区三区不卡| 亚洲av片在线免费观看| 激情综合网激情国产av| 欧美韩中文精品有码视频在线| 伊人久久精品久久亚洲一区| 精品无码一区二区三区电影| 亚洲一区二区不卡av| 久久人人97超碰爱香蕉| 婷婷久久香蕉五月综合加勒比| 伊人精品成人久久综合97| 中文字幕亚洲无线码A| 又白又嫩毛又多15p| 国产高清亚洲一区亚洲二区| 亚洲精品综合网二三区| 午夜福利偷拍国语对白| 黑人玩弄人妻中文在线| 国产一区二区黄色在线观看| 少妇高潮太爽了在线视频| 国产超高清麻豆精品传媒麻豆精品| 国产日韩久久免费影院| 国产精品中出一区二区三区| 痉挛高潮喷水av无码免费| 久久精品久久电影免费理论片| 麻豆a级片| 国产一区二区三区导航| 刚察县| 性欧美欧美巨大69| 亚洲成在人线在线播放无码| 麻豆一区二区三区精品视频| 国产麻豆一区二区精彩视频| 中文有无人妻vs无码人妻激烈| 成年女人永久免费观看视频| 久久欧洲精品成av人片| 久视频久免费视频久免费| 欧洲美熟女乱又伦免费视频| 国产一区二区三区小说| 午夜夜福利一区二区三区| 国产精品久久久久久久专区| 少妇久久久被弄到高潮|