string.templatelib — obsługa łańcuchów szablonowych

Ten moduł zapewnia obsługę łańcuchów szablonowych (t-strings) zgodnie z definicją w PEP 750. Łańcuchy szablonowe tworzy się przy użyciu przedrostka t i zapewniają one dostęp zarówno do literalnych części łańcucha, jak i do interpolowanych wartości przed ich połączeniem.

Dostępność: Łańcuchy szablonowe nie są obsługiwane na kamerach OpenMV Cam opartych na STM32. Są dostępne wyłącznie na kamerach OpenMV Cam opartych na Alif i i.MX RT.

Klasy

class string.templatelib.Template(*args)

Reprezentuje łańcuch szablonowy. Obiekty Template są zwykle tworzone przez składnię t-string (t"..."), ale można je również skonstruować bezpośrednio przy użyciu konstruktora.

strings

Krotka literałów łańcuchowych, które pojawiają się pomiędzy interpolacjami.

interpolations

Krotka obiektów Interpolation reprezentujących interpolowane wyrażenia.

values

Właściwość tylko do odczytu, która zwraca krotkę zawierającą atrybut value z każdej interpolacji w szablonie.

__iter__() Iterator

Iteruje po zawartości szablonu, zwracając części łańcuchowe i obiekty Interpolation w kolejności, w jakiej się pojawiają. Puste łańcuchy są pomijane.

__add__(other: Template) Template

Łączy dwa szablony. Zwraca nowy Template łączący łańcuchy i interpolacje z obu szablonów.

Wyrzuca:

TypeError – jeśli other nie jest obiektem Template

Łączenie szablonu z str jest zabronione, aby uniknąć niejednoznaczności co do tego, czy łańcuch powinien być traktowany jako literał, czy jako interpolacja:

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 = '')

Reprezentuje interpolowane wyrażenie wewnątrz łańcucha szablonowego. Wszystkie argumenty można przekazać jako argumenty nazwane.

value

Obliczona wartość interpolowanego wyrażenia.

expression

Reprezentacja łańcuchowa wyrażenia w postaci, w jakiej pojawiło się w łańcuchu szablonowym.

conversion

Specyfikator konwersji ('s' lub 'r'), jeśli jest obecny, w przeciwnym razie None. Należy pamiętać, że MicroPython nie obsługuje konwersji 'a'.

format_spec

Łańcuch specyfikacji formatu, jeśli jest obecny, w przeciwnym razie pusty łańcuch.

Składnia łańcuchów szablonowych

Łańcuchy szablonowe używają tej samej składni co f-stringi, ale z przedrostkiem t

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

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

Specyfikatory konwersji

Łańcuchy szablonowe przechowują specyfikatory konwersji jako metadane. W przeciwieństwie do f-stringów konwersja nie jest stosowana automatycznie:

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

Kod przetwarzający musi jawnie zastosować konwersje w razie potrzeby.

Specyfikacje formatu

Specyfikacje formatu są przechowywane jako metadane w obiekcie Interpolation. W przeciwieństwie do f-stringów formatowanie nie jest stosowane automatycznie:

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

Zgodnie z PEP 750 kod przetwarzający nie jest zobowiązany do używania specyfikacji formatu, ale gdy są one obecne, powinny być respektowane i w miarę możliwości odpowiadać zachowaniu f-stringów.

Format debugowania

Format debugowania {expr=} jest obsługiwany:

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

Ważne

Zgodnie z PEP 750, w przeciwieństwie do f-stringów, łańcuchy szablonowe nie stosują automatycznie konwersji ani specyfikacji formatu. Jest to zamierzone, aby pozwolić kodowi przetwarzającemu kontrolować sposób ich obsługi. Kod przetwarzający musi jawnie obsłużyć te atrybuty.

MicroPython nie udostępnia wbudowanej funkcji format(). Zamiast niej użyj metod formatowania łańcuchów, takich jak str.format().

Przykład użycia

Podstawowe przetwarzanie bez obsługi formatu:

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)

Przetwarzanie szablonu z obsługą formatu:

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"

Przykład ucieczki znaków 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;"

Zobacz także