string.templatelib --- پشتیبانی از رشته‌قالب‌های لفظی

کد منبع: Lib/string/templatelib.py


رشته‌های قالب

اضافه شده در نسخه‌ی 3.14.

رشته‌های الگویی سازوکاری برای پردازش سفارشی رشته‌ها هستند. آن‌ها انعطاف‌پذیری کامل اف‌استرینگ‌ها پایتون را دارند، اما یک نمونه Template برمی‌گردانند که امکان دسترسی به بخش‌های ایستا و درون‌یابی‌شده (داخل آکولادها) از یک رشته را پیش از ترکیب شدن آن‌ها می‌دهد.

برای نوشتن یک تی‌استرینگ (t-string)، به‌جای پیشوند 'f' از پیشوند 't' استفاده کنید، به این صورت:

>>> pi = 3.14
>>> t't-strings are new in Python {pi!s}!'
Template(
   strings=('t-strings are new in Python ', '!'),
   interpolations=(Interpolation(3.14, 'pi', 's', ''),)
)

انواع

class string.templatelib.Template

کلاس Template محتوای یک رشته‌ی قالب را توصیف می‌کند. این کلاس تغییرناپذیر است، به این معنا که ویژگی‌های یک قالب قابل انتساب مجدد نیستند.

رایج‌ترین روش برای ایجاد نمونه‌ای از Template، استفاده از سینتکس لفظی رشته‌ی الگو است. این سینتکس دقیقاً مشابه سینتکس اف‌استرینگ‌ها است، با این تفاوت که از پیشوند t به‌جای f استفاده می‌کند:

>>> cheese = 'Red Leicester'
>>> template = t"We're fresh out of {cheese}, sir."
>>> type(template)
<class 'string.templatelib.Template'>

قالب‌ها به‌صورت دنباله‌هایی از strings لفظی و interpolations پویا ذخیره می‌شوند. یک ویژگی values مقادیر درون‌یابی‌ها را نگه می‌دارد:

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.strings
('Ah! We do have ', '.')
>>> template.interpolations
(Interpolation('Camembert', ...),)
>>> template.values
('Camembert',)

تاپل strings یک عنصر بیشتر از interpolations و values دارد؛ درون‌یابی‌ها (interpolations) بین رشته‌ها قرار می‌گیرند. درک این موضوع هنگامی که تاپل‌ها هم‌تراز باشند آسان‌تر است

template.strings:  ('Ah! We do have ',              '.')
template.values:   (                   'Camembert',    )

ویژگی‌ها

strings: tuple[str, ...]

یک tuple از رشته‌های ثابت در الگو.

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.strings
('Ah! We do have ', '.')

رشته‌های خالی در تاپل گنجانده شده‌اند:

>>> response = 'We do have '
>>> cheese = 'Camembert'
>>> template = t'Ah! {response}{cheese}.'
>>> template.strings
('Ah! ', '', '.')

تاپل strings هرگز خالی نیست و همیشه شامل یک رشته بیشتر از تاپل‌های interpolations و values است:

>>> t''.strings
('',)
>>> t''.values
()
>>> t'{'cheese'}'.strings
('', '')
>>> t'{'cheese'}'.values
('cheese',)
interpolations: tuple[Interpolation, ...]

یک tuple از درون‌یابی‌ها در قالب.

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.interpolations
(Interpolation('Camembert', 'cheese', None, ''),)

تاپل interpolations ممکن است خالی باشد و همواره یک مقدار کمتر از تاپل strings دارد:

>>> t'Red Leicester'.interpolations
()
values: tuple[object, ...]

تاپلی از تمام مقادیر درون‌یابی‌شده در قالب.

>>> cheese = 'Camembert'
>>> template = t'Ah! We do have {cheese}.'
>>> template.values
('Camembert',)

تاپل values همیشه طولی برابر با تاپل interpolations دارد. این تاپل همیشه معادل tuple(i.value for i in template.interpolations) است.

متدها

__new__(*args: str | Interpolation)

هرچند سینتکس لفظی رایج‌ترین روش برای ایجاد یک Template است، اما می‌توان آن‌ها را مستقیماً با استفاده از سازنده نیز ایجاد کرد:

>>> from string.templatelib import Interpolation, Template
>>> cheese = 'Camembert'
>>> template = Template(
...     'Ah! We do have ', Interpolation(cheese, 'cheese'), '.'
... )
>>> list(template)
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

اگر چندین رشته به‌صورت متوالی ارسال شوند، به یک مقدار واحد در ویژگی strings الحاق می‌شوند. برای مثال، کد زیر یک Template با یک رشته نهایی واحد ایجاد می‌کند:

>>> from string.templatelib import Template
>>> template = Template('Ah! We do have ', 'Camembert', '.')
>>> template.strings
('Ah! We do have Camembert.',)

اگر چند درون‌یابی (interpolation) به‌صورت متوالی ارسال شوند، به‌عنوان درون‌یابی‌های جداگانه در نظر گرفته می‌شوند و یک رشته خالی بین آن‌ها درج می‌شود. برای مثال، کد زیر یک قالب با جای‌نگهدارهای خالی در ویژگی strings ایجاد می‌کند:

>>> from string.templatelib import Interpolation, Template
>>> template = Template(
...     Interpolation('Camembert', 'cheese'),
...     Interpolation('.', 'punctuation'),
... )
>>> template.strings
('', '', '')
iter(template)

قالب را پیمایش می‌کند و هر رشته غیرخالی و Interpolation را به ترتیب صحیح برمی‌گرداند:

>>> cheese = 'Camembert'
>>> list(t'Ah! We do have {cheese}.')
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

ملاحظه

رشته‌های خالی در پیمایش گنجانده نمی‌شوند:

>>> response = 'We do have '
>>> cheese = 'Camembert'
>>> list(t'Ah! {response}{cheese}.')
['Ah! ',
 Interpolation('We do have ', 'response', None, ''),
 Interpolation('Camembert', 'cheese', None, ''),
 '.']
template + other
template += other

این قالب را با دیگری الحاق می‌کند و یک نمونه‌ی جدید از Template برمی‌گرداند:

>>> cheese = 'Camembert'
>>> list(t'Ah! ' + t'We do have {cheese}.')
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

الحاق یک Template و یک str پشتیبانی نمی‌شود. این به این دلیل است که مشخص نیست آیا باید با رشته به‌عنوان یک رشته ایستا رفتار شود یا به‌عنوان یک درون‌یابی (interpolation). اگر بخواهید یک Template را با یک رشته الحاق کنید، باید یا رشته را مستقیماً در یک Template قرار دهید (تا به‌عنوان یک رشته ایستا با آن رفتار شود) یا از یک Interpolation استفاده کنید (تا به‌عنوان پویا با آن رفتار شود):

>>> from string.templatelib import Interpolation, Template
>>> template = t'Ah! '
>>> # Treat 'We do have ' as a static string
>>> template += Template('We do have ')
>>> # Treat cheese as an interpolation
>>> cheese = 'Camembert'
>>> template += Template(Interpolation(cheese, 'cheese'))
>>> list(template)
['Ah! We do have ', Interpolation('Camembert', 'cheese', None, '')]
class string.templatelib.Interpolation

نوع Interpolation نشان‌دهنده‌ی یک عبارت درون یک رشته‌ی قالب است. این نوع تغییرناپذیر است، به این معنا که ویژگی‌های یک درون‌یابی (interpolation) را نمی‌توان مجدداً مقداردهی کرد.

درون‌یابی‌ها از تطبیق الگو پشتیبانی می‌کنند و به شما امکان می‌دهند با استفاده از دستور match، آن‌ها را بر اساس ویژگی‌هایشان تطبیق دهید:

>>> from string.templatelib import Interpolation
>>> interpolation = t'{1. + 2.:.2f}'.interpolations[0]
>>> interpolation
Interpolation(3.0, '1. + 2.', None, '.2f')
>>> match interpolation:
...     case Interpolation(value, expression, conversion, format_spec):
...         print(value, expression, conversion, format_spec, sep=' | ')
...
3.0 | 1. + 2. | None | .2f

درون‌یابی‌ها نسبت به انواع مقدارهایشان عام هستند.

ویژگی‌ها

value: object

مقدار ارزیابی‌شده‌ی درون‌یابی.

>>> t'{1 + 2}'.interpolations[0].value
3
expression: str

برای درون‌یابی‌های ایجادشده با مقادیر لفظی t-string، expression متن عبارتی است که درون آکولادها ({ و }) یافت می‌شود؛ این متن شامل هرگونه فضای خالی است، خود آکولادها را شامل نمی‌شود و در صورت وجود هرکدام، پیش از نخستین !، : یا = پایان می‌یابد. برای درون‌یابی‌های ایجادشده به‌صورت دستی، expression رشته‌ی دلخواهی است که هنگام ساخت نمونه‌ی درون‌یابی ارائه می‌شود.

توصیه می‌کنیم از عبارات معتبر پایتون یا رشته خالی برای فیلد expression نمونه‌های Interpolation که به‌صورت دستی ایجاد شده‌اند استفاده کنید، اگرچه این موضوع در ران‌تایم اعمال نمی‌شود.

>>> t'{1 + 2}'.interpolations[0].expression
'1 + 2'
conversion: Literal['a', 'r', 's'] | None

تبدیلی که باید روی مقدار اعمال شود، یا None.

conversion تبدیل اختیاری برای اعمال روی مقدار است:

>>> t'{1 + 2!a}'.interpolations[0].conversion
'a'

توجه

برخلاف اف‌استرینگ‌ها، که در آن‌ها تبدیل‌ها به‌صورت خودکار اعمال می‌شوند، رفتار مورد انتظار در تی‌استرینگ‌ها (t-strings) این است که کدی که Template را پردازش می‌کند، تصمیم بگیرد که conversion را چگونه تفسیر کند و آیا آن را اعمال کند یا خیر. برای سهولت، می‌توان از تابع convert() برای تقلید از رفتار تبدیل‌ها در اف‌استرینگ‌ها استفاده کرد.

format_spec: str

مشخصات قالب‌بندی برای اعمال روی مقدار.

format_spec یک رشته‌ی اختیاری و دلخواه است که به‌عنوان مشخصه قالب برای نمایش مقدار استفاده می‌شود:

>>> t'{1 + 2:.2f}'.interpolations[0].format_spec
'.2f'

توجه

برخلاف اف‌استرینگ‌ها، که در آن‌ها مشخصات قالب‌بندی به‌طور خودکار از طریق پروتکل format() اعمال می‌شوند، رفتار مورد انتظار در تی‌استرینگ‌ها (t-strings) این است که کدی که درون‌یابی را پردازش می‌کند، تصمیم بگیرد که چگونه مشخصات قالب‌بندی را تفسیر کند و آیا آن را اعمال کند یا خیر. در نتیجه، مقادیر format_spec در درون‌یابی‌ها می‌توانند رشته‌های دلخواه باشند، از جمله آن‌هایی که با پروتکل format() مطابقت ندارند.

متدها

__new__(value: object, expression: str, conversion: Literal['a', 'r', 's'] | None = None, format_spec: str = '')

یک شیء Interpolation جدید را از اجزای تشکیل‌دهنده ایجاد کنید.

پارامترها:
  • value -- نتیجه‌ی ارزیابی‌شده و در محدوده‌ی درون‌یابی.

  • expression -- متن یک عبارت معتبر پایتون، یا یک رشته خالی.

  • conversion -- تبدیل مورد استفاده، یکی از None، 'a'، 'r' یا 's' است.

  • format_spec -- رشته‌ای اختیاری و دلخواه که به‌عنوان مشخصه قالب برای نمایش مقدار استفاده می‌شود.

توابع کمکی

string.templatelib.convert(obj, /, conversion)

معنای تبدیل در لفظی رشته‌ی قالب‌بندی‌شده را بر شیء داده‌شده obj اعمال می‌کند. این کار اغلب برای منطق سفارشی پردازش رشته‌ی قالب مفید است.

در حال حاضر از سه پرچم تبدیل پشتیبانی می‌شود:

  • 's' که str() را روی مقدار فراخوانی می‌کند (مانند !s

  • 'r' که repr() را فراخوانی می‌کند (مانند !r)، و

  • 'a' که ascii() را فراخوانی می‌کند (مانند !a).

اگر پرچم تبدیل None باشد، obj بدون تغییر بازگردانده می‌شود.