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

Quellcode: Lib/string/templatelib.py


Template-Strings

Added in version 3.14.

Template-Strings sind ein Mittel zur eigenen Verarbeitung von Zeichenketten. Sie bieten die volle Beweglichkeit von Pythons f-Strings, geben aber eine Template-Instanz zurück, die Zugriff auf die statischen und die interpolierten Teile einer Zeichenkette gibt – letztere in geschweiften Klammern –, und zwar bevor sie zusammengesetzt werden.

Um einen t-String zu schreiben, verwende das Präfix 't' statt 'f', so wie hier:

>>> 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, das heißt, die Attribute eines Templates lassen sich nicht neu zuweisen.

Am häufigsten erzeugt man eine Template-Instanz über die Syntax der Template-String-Literale. Diese Syntax ist mit der von f-strings identisch, nur dass sie das Präfix t statt f verwendet:

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

Templates werden als Folgen aus wörtlichen strings und dynamischen interpolations gespeichert. Das 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, denn die Interpolationen „gehören“ zwischen die Zeichenketten. Untereinander ausgerichtet ist das leichter zu erkennen

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

Attribute

strings: tuple[str, ...]

Ein tuple der statischen Zeichenketten des Templates.

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

Leere Zeichenketten sind im Tupel enthalten:

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

Das Tupel strings ist nie leer und enthält immer eine Zeichenkette mehr als die Tupel interpolations und values:

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

Ein tuple der Interpolationen des Templates.

>>> 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 des Templates.

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

Das Tupel values hat immer dieselbe Länge wie das Tupel interpolations. Es entspricht stets tuple(i.value for i in template.interpolations).

Methoden

__new__(*args: str | Interpolation)

Am häufigsten erzeugt man ein Template über die Literalsyntax, es geht aber auch unmittelbar über den Konstruktor:

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

Werden mehrere Zeichenketten hintereinander übergeben, werden sie im Attribut strings zu einem einzigen Wert zusammengefügt. Der folgende Code erzeugt zum Beispiel ein Template mit einer einzigen abschließenden Zeichenkette:

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

Werden mehrere Interpolationen hintereinander übergeben, gelten sie als eigenständige Interpolationen, und zwischen sie wird eine leere Zeichenkette eingefügt. Der folgende Code erzeugt zum Beispiel 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 jede nicht leere Zeichenkette 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 Zeichenketten sind in der Iteration nicht enthalten:

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

Ein Template mit einem str zu verketten, wird nicht unterstützt. Der Grund: Es wäre unklar, ob die Zeichenkette als statische Zeichenkette oder als Interpolation gelten soll. Willst du ein Template mit einer Zeichenkette verketten, packe die Zeichenkette entweder unmittelbar in ein Template, damit sie als statisch gilt, oder verwende eine Interpolation, damit sie als dynamisch gilt:

>>> 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 stellt einen Ausdruck innerhalb eines Template-Strings dar. Er ist unveränderlich, das heißt, die Attribute einer Interpolation lassen sich nicht neu zuweisen.

Interpolationen unterstützen Mustervergleiche: Mit der match-Anweisung lässt sich gegen ihre Attribute abgleichen:

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

Interpolationen sind generisch über die Typen ihrer Werte.

Attribute

value: object

Der ausgewertete Wert der Interpolation.

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

Bei Interpolationen, die aus t-String-Literalen entstehen, ist expression der Ausdruckstext innerhalb der geschweiften Klammern ({ & }), einschließlich aller Leerzeichen, ohne die Klammern selbst und endend vor dem ersten !, : oder =, sofern eines davon vorhanden ist. Bei von Hand erzeugten Interpolationen ist expression die beliebige Zeichenkette, die beim Erzeugen der Interpolationsinstanz übergeben wurde.

Für das Feld expression von Hand erzeugter Interpolation-Instanzen empfehlen wir gültige Python-Ausdrücke oder die leere Zeichenkette, auch wenn das zur Laufzeit nicht erzwungen wird.

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

Die auf den Wert anzuwendende Umwandlung oder None.

conversion ist die optionale Umwandlung, die auf den Wert angewandt wird:

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

Bemerkung

Anders als bei f-Strings, wo Umwandlungen selbsttätig angewandt werden, ist bei t-Strings vorgesehen, dass der Code, der Template verarbeitet, entscheidet, wie conversion zu deuten ist und ob sie angewandt wird. Der Bequemlichkeit halber lässt sich mit der Funktion convert() das Umwandlungsverhalten von f-Strings nachbilden.

format_spec: str

Die auf den Wert anzuwendende Formatspezifikation.

format_spec ist eine optionale, beliebige Zeichenkette, die als Formatspezifikation für die Darstellung des Wertes dient:

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

Bemerkung

Anders als bei f-Strings, wo Formatspezifikationen selbsttätig über das format()-Protokoll angewandt werden, ist bei t-Strings vorgesehen, dass der Code, der die Interpolation verarbeitet, entscheidet, wie die Formatspezifikation zu deuten ist und ob sie angewandt wird. Deshalb dürfen format_spec-Werte in Interpolationen beliebige Zeichenketten sein, auch solche, die nicht dem format()-Protokoll entsprechen.

Methoden

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

Erzeugt ein neues Interpolation-Objekt aus seinen Bestandteilen.

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

  • expression – Der Text eines gültigen Python-Ausdrucks oder eine leere Zeichenkette.

  • conversion – Die zu verwendende Umwandlung, eines von None, 'a', 'r' oder 's'.

  • format_spec – Eine optionale, beliebige Zeichenkette, die als Formatspezifikation für die Darstellung des Wertes dient.

Hilfsfunktionen

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

Wendet das Umwandlungsverhalten formatierter Zeichenkettenliterale auf das übergebene Objekt obj an. Das ist für eigene Verarbeitungslogik von Template-Strings oft nützlich.

Derzeit werden drei Umwandlungsflags unterstützt:

  • 's', das str() auf den Wert anwendet (wie !s),

  • 'r', das repr() anwendet (wie !r), und

  • 'a', das ascii() anwendet (wie !a).

Ist das Umwandlungsflag None, wird obj unverändert zurückgegeben.