string.templatelib — Compatibilidad con cadenas de plantilla

Este módulo proporciona compatibilidad con las cadenas de plantilla (t-strings) según se define en PEP 750. Las cadenas de plantilla se crean usando el prefijo t y dan acceso tanto a las partes literales de la cadena como a los valores interpolados antes de que se combinen.

Disponibilidad: Las cadenas de plantilla no son compatibles con las OpenMV Cam basadas en STM32. Solo están disponibles en las OpenMV Cam basadas en Alif e i.MX RT.

Clases

class string.templatelib.Template(*args)

Representa una cadena de plantilla. Los objetos Template normalmente se crean con la sintaxis de t-string (t"..."), pero también pueden construirse directamente usando el constructor.

strings

Una tupla de literales de cadena que aparecen entre las interpolaciones.

interpolations

Una tupla de objetos Interpolation que representan las expresiones interpoladas.

values

Una propiedad de solo lectura que devuelve una tupla con el atributo value de cada interpolación de la plantilla.

__iter__() Iterator

Itera sobre el contenido de la plantilla, devolviendo las partes de cadena y los objetos Interpolation en el orden en que aparecen. Las cadenas vacías se omiten.

__add__(other: Template) Template

Concatena dos plantillas. Devuelve una nueva Template que combina las cadenas e interpolaciones de ambas plantillas.

Muestra:

TypeError – si other no es una Template

La concatenación de una plantilla con un str está prohibida para evitar la ambigüedad sobre si la cadena debe tratarse como un literal o como una interpolación:

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

Representa una expresión interpolada dentro de una cadena de plantilla. Todos los argumentos pueden pasarse como argumentos con nombre.

value

El valor evaluado de la expresión interpolada.

expression

La representación en cadena de la expresión tal como apareció en la cadena de plantilla.

conversion

El especificador de conversión ('s' o 'r') si está presente, de lo contrario None. Tenga en cuenta que MicroPython no admite la conversión 'a'.

format_spec

La cadena de especificación de formato si está presente, de lo contrario una cadena vacía.

Sintaxis de las cadenas de plantilla

Las cadenas de plantilla usan la misma sintaxis que las f-strings pero con un prefijo t:

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

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

Especificadores de conversión

Las cadenas de plantilla almacenan los especificadores de conversión como metadatos. A diferencia de las f-strings, la conversión no se aplica automáticamente:

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

El código de procesamiento debe aplicar explícitamente las conversiones cuando sea necesario.

Especificaciones de formato

Las especificaciones de formato se almacenan como metadatos en el objeto Interpolation. A diferencia de las f-strings, el formato no se aplica automáticamente:

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

Según la PEP 750, el código de procesamiento no está obligado a usar las especificaciones de formato, pero cuando están presentes deben respetarse y coincidir con el comportamiento de las f-strings siempre que sea posible.

Formato de depuración

El formato de depuración {expr=} es compatible:

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

Importante

Según la PEP 750, a diferencia de las f-strings, las cadenas de plantilla no aplican automáticamente conversiones ni especificaciones de formato. Esto es así por diseño para permitir que el código de procesamiento controle cómo se manejan. El código de procesamiento debe manejar explícitamente estos atributos.

MicroPython no proporciona la función incorporada format(). Use métodos de formato de cadenas como str.format() en su lugar.

Ejemplo de uso

Procesamiento básico sin compatibilidad con formato:

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)

Procesamiento de una plantilla con compatibilidad con formato:

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"

Ejemplo de escape de 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;"

Véase también