۲۷ مهر ۱۴۰۴

Techboy

اخبار و اطلاعات روز تکنولوژی

چگونه از رشته‌های قالبی در پایتون ۳.۱۴ استفاده کنیم

قالب‌های جدید پایتون، یا t-strings، راهی بسیار قدرتمندتر برای قالب‌بندی داده‌ها نسبت به f-strings قدیمی فراهم می‌کند.

قالب‌های جدید پایتون، یا t-strings، راهی بسیار قدرتمندتر برای قالب‌بندی داده‌ها نسبت به f-strings قدیمی فراهم می‌کند.

قابِل قالب‌بندی شناخته‌شده، یا ویژگی رشته f-string در Python، روشی مناسب برای چاپ متغیرها به‌عنوان بخشی از یک رشته فراهم می‌کند. اما اجازهٔ تعامل با نحوهٔ ایجاد رشته‌ها از آن متغیرها را نمی‌دهد. انجام کارهایی مثل بررسی هر متغیر هنگام وارد شدن به رشته و انجام عملی بر اساس آن تقریباً دشوار یا حتی غیرممکن است.

Python 3.14 ویژگی جدیدی به نام رشته قالب یا نوع t-string دارد. یک t-string به‌ظاهر شبیه f-string است، اما برای کاری کاملاً متفاوت طراحی شده است. به‌جای تنها چاپ رشته با متغیرهای درج‌شده در آن، t-string به شما امکان می‌دهد هر دو عنصر رشته و متغیرهای درج‌شده را به‌عنوان اجزای جداگانه پردازش کنید و هر نوع رشته‌ای که می‌خواهید از آن بسازید.

یک رشته قالب پایه

رشته‌های قالب شبیه f-strings به‌نظر می‌رسند. تنها تفاوت استفاده از t به‌جای f برای تعریف رشته است:

ame = "Davis" template = t"Hello, {name}"

n

اگر این یک f-string متعارف بود، می‌توانستیم print(template) را اجرا کنیم و خروجی Hello, Davis را دریافت کنیم. اما اگر سعی کنیم یک t-string را چاپ کنیم، رشته‌ای دریافت نمی‌کنیم. در عوض، نمایشی از شیء پایتون دریافت می‌کنیم:

Template(strings=('Hello ', ''), interpolations=(Interpolation('Davis', 'name', None, ''),))

به این دلیل است که t-strings برای چاپ مستقیم مدنظر نیستند. در عوض، کاری با محتوای آن‌ها انجام می‌دهیم با اعمال یک تابع یا روش کلاس.

یک شیء t-string شامل زیرشیءهای مختلفی است که می‌توانیم از طریق آن‌ها تکرار کنیم، که محتوای t-string را نشان می‌دهند:

  • شیء strings شامل تمام رشته‌های ثابت در قالب اصلی است—در این مورد، "Hello, " قبل از متغیر و رشتهٔ خالی "" پس از متغیر.
  • شیء interpolations شامل تمام جایگزینی‌های متغیرهای مختلف در t-string است. هر کدام یک شیء Interpolation جداگانه با داده‌های مربوط به مقدار، عبارت استفاده‌شده برای ایجاد آن و جزئیات مفید دیگر هستند.

اگر مستقیماً روی قالب تکرار کنید (for item in template:) هر عنصر قالب به‌ترتیب دریافت می‌کنید: رشتهٔ "Hello, "، شیء Interpolation نشان‌داده‌شده در بالا، و رشتهٔ "". این کار ترکیب یک رشتهٔ جدید از عناصر یک t-string را آسان می‌کند.

استفاده از رشته قالب

دوباره، هدف از یک رشته قالب این نیست که همان‌طور که هست چاپ شود، بلکه این است که به یک تابع منتقل شود که مسئولیت قالب‌بندی را بر عهده گیرد. برای مثال، یک پردازشگر سادهٔ رشته قالب برای نمایش نمایش رشته‌ای هر متغیر به صورت حروف بزرگ می‌تواند به شکل زیر باشد:

from string.templatelib import Template, Interpolation def t_upper(template: Template): output = [] for item in template: if isinstance(item, Interpolation): output.append(str(item).upper()) else: output.append(item) return "".join(output)

اگر t_upper() را روی قالب فوق اجرا کنیم، خروجی Hello, DAVIS را دریافت می‌کنیم.

توجه داشته باشید که در این کد یک خط وارد کردن داریم:

from string.templatelib import Template, Interpolation

string.templatelib یک ماژول جدید در کتابخانهٔ استاندارد پایتون ۳.۱۴ است که انواع مورد نیاز ما را نگهداری می‌کند: Template برای اشاره نوع به تابع، و Interpolation برای بررسی عناصری که از طریق آن‌ها تکرار می‌کنیم.

با این حال، برای ساخت رشته‌های قالب نیازی به string.templatelib نداریم. می‌توانیم این رشته‌ها را فقط با استفاده از سینتکس t-string در هرجایی از کد خود ساختاردهی کنیم.

یک مثال مفید از رشته قالب

برای مثال بهتر از اینکه رشته‌های قالب چقدر مفید و قدرتمند هستند، به کاری نگاه می‌کنیم که بدون آن‌ها بسیار دشوارتر می‌بود.

احتمالاً با پاکسازی HTML آشنا هستید، که عناصر خطرناک را از محتوای HTML حذف می‌کند تا فقط HTML امن نمایش داده شود. بسیاری از موتورهای قالب برای این کار وجود دارند. ما می‌توانیم همان کار را با رشته‌های قالب و موارد دیگر انجام دهیم:

from string.templatelib import Template, Interpolation import urllib.parse import html def clean(input:Template): output = [] inside_tag = False for item in input: if isinstance(item, Interpolation): escape = urllib.parse.quote if inside_tag else html.escape out_item = escape(str(item.value)) else: for l in item: if l in (""): inside_tag = not inside_tag out_item = item output.append(out_item) return "".join(output) name="" print(clean(t'Hello, {name}'))

تابع clean() یک رشته قالب را دریافت می‌کند و آن را طوری پاک‌سازی می‌کند که هر گونه براکت‌های HTML (< و >) به نمادهای بی‌ضرر (&lt; و &gt;) تبدیل شوند. رشته‌های احاطه‌کننده در رشته قالب تغییر نمی‌کنند.

برای انجام این کار، تابع clean() سه نوع پردازش مختلف انجام می‌دهد:

  1. اگر تابع یک رشته معمولی را که شامل HTML است که می‌خواهیم رندر کنیم، پیدا کند، آن رشته به همان شکل به خروجی اضافه می‌شود. همچنین وضعیت اینکه در آن لحظه داخل یک تگ HTML هستیم یا خیر را پیگیری می‌کند. (الگوریتم استفاده‌شده بسیار پیشرفته نیست؛ این فقط یک مثال است.)
  2. اگر تابع یک جایگزینی (interpolation) را پیدا کند و داخل یک تگ HTML باشد (مثلاً در بخش <a href="/user/{name}"> قالب)، از urllib.parse.quote برای فرار دادن رشته استفاده می‌کند. این اطمینان می‌دهد که رشته می‌تواند بین کوتیشن‌های داخل تگ بدون خراب شدن قرار گیرد، و ایمن برای URL باشد.
  3. اگر تابع یک جایگزینی را خارج از تگ HTML پیدا کند، از تابع دیگری برای فرار دادن آن (html.escape) استفاده می‌کند. این نیز موجودیت‌های HTML را فرار می‌دهد اما کوتیشن‌ها را به‌طور متفاوتی پردازش می‌کند و نیازی به ایمنی URL ندارد (چون در خارج از تگ‌ها به این مورد نیازی نداریم).

این کد را اجرا کنید و خروجی زیر را دریافت خواهید کرد:

Hello, <David's Friend>

توجه کنید که فاصله‌ها در نسخهٔ URL رشته فرار داده شده‌اند، اما فاصله‌ها در متن اصلی فرار داده نشده‌اند. این نوع پردازش دقیق هر متغیر به راحتی در یک f-string قابل انجام نیست، اگر امکان‌پذیر هم باشد.

مزیت t-strings

یک مزیت بزرگ استفاده از t-strings این است که می‌توانید t-string را به توابع پردازش متفاوت منتقل کنید. همان t-string می‌تواند برای تولید انواع خروجی‌های مختلف فقط با تغییر تابع اعمال‌شده استفاده شود. به این ترتیب، ساختن t-string و رندر کردن آن به متن می‌تواند کاملاً عملیات‌های جداگانه‌ای باشد. در همان زمان، رندر می‌تواند با دسترسی کامل به ورودی اصلی انجام شود، از جمله جزئیات مربوط به هر متغیر درج‌شده.