string.templatelib — Unterstützung für Template-String-Literale

Quellcode: Lib/string/templatelib.py


Template-Strings

Hinzugefügt in Version 3.14.

Template-Strings sind ein Mechanismus zur benutzerdefinierten String-Verarbeitung. Sie verfügen über die volle Flexibilität von Pythons f-Strings, geben jedoch eine Template-Instanz zurück, die Zugriff auf die statischen und interpolierten (in geschweiften Klammern) Teile eines Strings gewährt, *bevor* diese kombiniert werden.

Um einen t-String zu schreiben, verwenden Sie das Präfix 't' anstelle von 'f', wie folgt:

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

Typen

class string.templatelib.Template

Die Klasse Template beschreibt den Inhalt eines Template-Strings. Sie ist unveränderlich, was bedeutet, dass Attribute eines Templates nicht neu zugewiesen werden können.

Der gebräuchlichste Weg, eine Template-Instanz zu erstellen, ist die Verwendung der Template-String-Literal-Syntax. Diese Syntax ist identisch mit der von f-Strings, außer dass sie ein t-Präfix anstelle eines f verwendet.

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

Templates werden als Sequenzen von statischen strings und dynamischen interpolations gespeichert. Ein Attribut values enthält die Werte der Interpolationen.

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

Das Tupel strings hat ein Element mehr als interpolations und values; die Interpolationen „gehören“ zwischen die Strings. Dies lässt sich leichter verstehen, wenn die Tupel ausgerichtet sind:

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

Attribute

strings: tuple[str, ...]

Ein Tupel der statischen Strings im Template.

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

Leere Strings *werden* in das Tupel aufgenommen.

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

Das Tupel strings ist niemals leer und enthält immer einen String mehr als die Tupel interpolations und values.

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

Ein Tupel der Interpolationen im Template.

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

Das Tupel interpolations kann leer sein und enthält immer einen Wert weniger als das Tupel strings.

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

Ein Tupel aller interpolierten Werte im Template.

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

Das Tupel values hat immer die gleiche Länge wie das Tupel interpolations. Es ist immer äquivalent zu tuple(i.value for i in template.interpolations).

Methoden

__new__(*args: str | Interpolation)

Während die Literal-Syntax der gebräuchlichste Weg ist, ein Template zu erstellen, ist es auch möglich, sie direkt über den Konstruktor zu erstellen.

>>> 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, ''), '.']

Wenn mehrere Strings nacheinander übergeben werden, werden sie zu einem einzigen Wert im Attribut strings zusammengefasst. Zum Beispiel erstellt der folgende Code ein Template mit einem einzigen endgültigen String:

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

Wenn mehrere Interpolationen nacheinander übergeben werden, werden sie als separate Interpolationen behandelt und ein leerer String wird zwischen ihnen eingefügt. Zum Beispiel erstellt der folgende Code ein Template mit leeren Platzhaltern im Attribut strings:

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

Iteriert über das Template und liefert jeden nicht-leeren String und jede Interpolation in der richtigen Reihenfolge.

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

Vorsicht

Leere Strings werden *nicht* in die Iteration aufgenommen.

>>> 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

Verkettet dieses Template mit einem anderen und gibt eine neue Template-Instanz zurück.

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

Das Verketten eines Template und eines str wird *nicht* unterstützt. Dies liegt daran, dass unklar ist, ob der String als statischer String oder als Interpolation behandelt werden soll. Wenn Sie ein Template mit einem String verketten möchten, sollten Sie entweder den String direkt in ein Template (um ihn als statischen String zu behandeln) oder eine Interpolation (um ihn als dynamisch zu behandeln) verpacken.

>>> 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

Der Typ Interpolation repräsentiert einen Ausdruck innerhalb eines Template-Strings. Er ist unveränderlich, was bedeutet, dass Attribute einer Interpolation nicht neu zugewiesen werden können.

Interpolationen unterstützen Pattern Matching, was Ihnen ermöglicht, Attribute mit der match-Anweisung abzugleichen.

>>> 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

Attribute

value: object

Der ausgewertete Wert der Interpolation.

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

Für Interpolationen, die durch t-String-Literale erstellt wurden, ist expression der Ausdruckstext innerhalb der geschweiften Klammern ({ & }), einschließlich aller Leerzeichen, ohne die geschweiften Klammern selbst und endend vor dem ersten !, : oder =, falls vorhanden. Bei manuell erstellten Interpolationen ist expression der beliebige String, der bei der Erstellung der Interpolationsinstanz bereitgestellt wird.

Wir empfehlen die Verwendung gültiger Python-Ausdrücke oder des leeren Strings für das Feld expression von manuell erstellten Interpolation-Instanzen, obwohl dies zur Laufzeit nicht erzwungen wird.

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

Die auf den Wert anzuwendende Konvertierung oder None.

Die conversion ist die optionale Konvertierung, die auf den Wert angewendet werden soll.

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

Hinweis

Im Gegensatz zu f-Strings, bei denen Konvertierungen automatisch angewendet werden, ist das erwartete Verhalten bei t-Strings, dass Code, der das Template *verarbeitet*, entscheidet, wie die conversion interpretiert und ob sie angewendet werden soll. Zur Vereinfachung kann die Funktion convert() verwendet werden, um die f-String-Konvertierungssemantik nachzuahmen.

format_spec: str

Die auf den Wert anzuwendende Formatierungsspezifikation.

Die format_spec ist ein optionaler, beliebiger String, der als Formatierungsspezifikation zur Darstellung des Werts verwendet wird.

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

Hinweis

Im Gegensatz zu f-Strings, bei denen Formatierungsspezifikationen automatisch über das format()-Protokoll angewendet werden, ist das erwartete Verhalten bei t-Strings, dass Code, der die Interpolation *verarbeitet*, entscheidet, wie die Formatierungsspezifikation interpretiert und ob sie angewendet werden soll. Infolgedessen können format_spec-Werte in Interpolationen beliebige Strings sein, einschließlich solcher, die nicht dem format()-Protokoll entsprechen.

Methoden

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

Erstellt ein neues Interpolation-Objekt aus Komponententeilen.

Parameter:
  • value – Das ausgewertete Ergebnis der Interpolation im aktuellen Gültigkeitsbereich.

  • expression – Der Text eines gültigen Python-Ausdrucks oder ein leerer String.

  • conversion – Die zu verwendende Konvertierung, einer von None, 'a', 'r' oder 's'.

  • format_spec – Eine optionale, beliebige Zeichenkette, die als Formatierungsspezifikation zur Darstellung des Werts verwendet wird.

Hilfsfunktionen

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

Wendet die formatierten String-Literal-Konvertierungssemantiken auf das gegebene Objekt obj an. Dies ist häufig für benutzerdefinierte Logik zur Verarbeitung von Template-Strings nützlich.

Drei Konvertierungsflaggen werden derzeit unterstützt:

  • 's', welches str() auf den Wert aufruft (wie !s),

  • 'r', welches repr() aufruft (wie !r), und

  • 'a', welches ascii() aufruft (wie !a).

Wenn das Konvertierungsflag None ist, wird obj unverändert zurückgegeben.