string.templatelib --- دعم سلاسل القوالب

توفر هذه الوحدة دعماً لسلاسل القوالب (t-strings) كما هي معرّفة في PEP 750. تُنشأ سلاسل القوالب باستخدام البادئة t وتوفر الوصول إلى كل من الأجزاء النصية الحرفية والقيم المُستبدَلة قبل دمجها.

التوفر: سلاسل القوالب غير مدعومة على كاميرات OpenMV Cam المبنية على STM32. وهي متاحة فقط على كاميرات OpenMV Cam المبنية على Alif وi.MX RT.

الأصناف

class string.templatelib.Template(*args)

يمثّل سلسلة قالب. تُنشأ كائنات Template عادةً بصياغة t-string (t"...") لكن يمكن أيضاً إنشاؤها مباشرة باستخدام الباني.

strings

مجموعة من الحرفيات النصية التي تظهر بين عمليات الاستبدال.

interpolations

مجموعة من كائنات Interpolation تمثّل التعبيرات المُستبدَلة.

values

خاصية للقراءة فقط تُرجع مجموعة تحتوي على السمة value من كل عملية استبدال في القالب.

__iter__() Iterator

يكرّر على محتويات القالب، منتجاً الأجزاء النصية وكائنات Interpolation بالترتيب الذي تظهر به. تُحذف السلاسل الفارغة.

__add__(other: Template) Template

يدمج قالبين. يُرجع Template جديداً يجمع السلاسل وعمليات الاستبدال من كلا القالبين.

يثير:

TypeError -- إذا لم يكن other من نوع Template

دمج القالب مع str محظور لتجنب الالتباس حول ما إذا كان ينبغي معاملة السلسلة كحرفية أم كعملية استبدال:

t1 = t"Hello "
t2 = t"World"
result = t1 + t2  # Valid

# TypeError: cannot concatenate str to Template
result = t1 + "World"
class string.templatelib.Interpolation(value: Any, expression: str = '', conversion: str | None = None, format_spec: str = '')

يمثّل تعبيراً مُستبدَلاً داخل سلسلة قالب. يمكن تمرير جميع الوسيطات كوسيطات مفتاحية.

value

القيمة المُقيَّمة للتعبير المُستبدَل.

expression

التمثيل النصي للتعبير كما ظهر في سلسلة القالب.

conversion

محدّد التحويل ('s' أو 'r') إن وُجد، وإلا None. لاحظ أن MicroPython لا تدعم تحويل 'a'.

format_spec

سلسلة مواصفات التنسيق إن وُجدت، وإلا سلسلة فارغة.

صياغة سلاسل القوالب

تستخدم سلاسل القوالب الصياغة نفسها المستخدمة في f-strings لكن مع البادئة t

name = "World"
template = t"Hello {name}!"

# Access template components
print(template.strings)        # ('Hello ', '!')
print(template.values)         # ('World',)
print(template.interpolations[0].expression)  # 'name'

محدّدات التحويل

تخزّن سلاسل القوالب محدّدات التحويل كبيانات وصفية. وخلافاً لـ f-strings، لا يُطبَّق التحويل تلقائياً:

value = "test"
t = t"{value!r}"
# t.interpolations[0].value == "test" (not repr(value))
# t.interpolations[0].conversion == "r"

يجب على شيفرة المعالجة تطبيق التحويلات صراحةً عند الحاجة.

مواصفات التنسيق

تُخزَّن مواصفات التنسيق كبيانات وصفية في كائن Interpolation. وخلافاً لـ f-strings، لا يُطبَّق التنسيق تلقائياً:

pi = 3.14159
t = t"{pi:.2f}"
# t.interpolations[0].value == 3.14159 (not formatted)
# t.interpolations[0].format_spec == ".2f"

وفقاً لـ PEP 750، شيفرة المعالجة ليست ملزمة باستخدام مواصفات التنسيق، لكن عند وجودها ينبغي احترامها ومطابقة سلوك f-string حيثما أمكن.

صيغة التصحيح

صيغة التصحيح {expr=} مدعومة:

x = 42
t = t"{x=}"
# t.strings == ("x=", "")
# t.interpolations[0].expression == "x"
# t.interpolations[0].conversion == "r"

مهم

وفقاً لـ PEP 750، وخلافاً لـ f-strings، لا تطبّق سلاسل القوالب التحويلات أو مواصفات التنسيق تلقائياً. وهذا بحكم التصميم للسماح لشيفرة المعالجة بالتحكم في كيفية التعامل معها. يجب على شيفرة المعالجة التعامل مع هذه السمات صراحةً.

لا توفر MicroPython الدالة المضمّنة format(). استخدم طرق تنسيق السلاسل مثل str.format() بدلاً من ذلك.

مثال على الاستخدام

معالجة أساسية دون دعم التنسيق:

def simple_process(template):
    """Simple template processing"""
    parts = []
    for item in template:
        if isinstance(item, str):
            parts.append(item)
        else:
            parts.append(str(item.value))
    return "".join(parts)

معالجة قالب مع دعم التنسيق:

from string.templatelib import Template, Interpolation

def convert(value, conversion):
    """Apply conversion specifier to value"""
    if conversion == "r":
        return repr(value)
    elif conversion == "s":
        return str(value)
    return value

def process_template(template):
    """Process template with conversion and format support"""
    result = []
    for part in template:
        if isinstance(part, str):
            result.append(part)
        else:  # Interpolation
            value = convert(part.value, part.conversion)
            if part.format_spec:
                # Apply format specification using str.format
                value = ("{:" + part.format_spec + "}").format(value)
            else:
                value = str(value)
            result.append(value)
    return "".join(result)

pi = 3.14159
name = "Alice"
t = t"{name!r}: {pi:.2f}"
print(process_template(t))
# Output: "'Alice': 3.14"

# Other format specifications work too
value = 42
print(process_template(t"{value:>10}"))  # "        42"
print(process_template(t"{value:04d}"))  # "0042"

مثال على هروب HTML:

def html_escape(value):
    """Escape HTML special characters"""
    if not isinstance(value, str):
        value = str(value)
    return value.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")

def safe_html(template):
    """Convert template to HTML-safe string"""
    result = []
    for part in template:
        if isinstance(part, str):
            result.append(part)
        else:
            result.append(html_escape(part.value))
    return "".join(result)

user_input = "<script>alert('xss')</script>"
t = t"User said: {user_input}"
print(safe_html(t))
# Output: "User said: &lt;script&gt;alert('xss')&lt;/script&gt;"

انظر أيضاً