String-Interpolation in Python: Verfügbare Tools erkunden


Mit der String-Interpolation können Sie Strings erstellen, indem Sie Objekte an bestimmten Stellen in einer Ziel-String-Vorlage einfügen. Python verfügt über mehrere Tools zur String-Interpolation, darunter F-Strings, die Methode str.format() und den Modulo-Operator (%). Das string-Modul von Python stellt auch die Klasse Template bereit, die Sie für die String-Interpolation verwenden können.

In diesem Tutorial werden Sie:

  • Erfahren Sie, wie Sie f-strings für die eifrige String-Interpolation verwenden
  • Führen Sie eine lazy String-Interpolation mit der Methode str.format() durch
  • Lernen Sie die Grundlagen der Verwendung des Modulo-Operators (%) für die String-Interpolation kennen
  • Entscheiden Sie, ob Sie F-Strings oder die Methode str.format() für die Interpolation verwenden möchten
  • Erstellen Sie Vorlagen für die String-Interpolation mit string.Template

Um dieses Tutorial optimal nutzen zu können, sollten Sie mit Python-Strings vertraut sein, die durch die Klasse str dargestellt werden.

String-Interpolation in Python

Wenn Sie mit Zeichenfolgen arbeiten, stellen Sie manchmal Zeichenfolgen zusammen, indem Sie mehrere unterschiedliche Zeichenfolgenwerte verwenden. Zunächst könnten Sie den Plus-Operator (+) verwenden, um Zeichenfolgen in Python zu verketten. Dieser Ansatz führt jedoch zu Code mit vielen Anführungszeichen und Pluspunkten:

>>> name = "Pythonista"
>>> day = "Friday"  # Of course 😃

>>> "Hello, " + name + "! Today is " + day + "."
'Hello, Pythonista! Today is Friday.'

In diesem Beispiel erstellen Sie eine Zeichenfolge aus Text und einigen Variablen, die Zeichenfolgenwerte enthalten. Die vielen Pluszeichen erschweren das Lesen und Schreiben des Codes. Python muss einen besseren und saubereren Weg haben.

Der Modulo-Operator (%) wurde eingeführt, um die Syntax etwas zu verbessern:

>>> "Hello, %s! Today is %s." % (name, day)
'Hello, Pythonista! Today is Friday.'

In diesem Beispiel verwenden Sie den Modulo-Operator, um die Variablen name und day in die Zeichenfolgenliterale einzufügen. Der Vorgang des Erstellens von Zeichenfolgen durch Einfügen anderer Zeichenfolgen, wie Sie es hier getan haben, wird als Zeichenfolgeninterpolation bezeichnet.

Die Zeichenkombination %s wird als Konvertierungsspezifizierer bezeichnet. Sie fungieren als Ersatzfelder. Der Operator % markiert den Anfang des Spezifizierers, während der Buchstabe s den Konvertierungstyp angibt und dem Operator mitteilt, dass Sie die Eingabe konvertieren möchten Objekt in einen String. Weitere Informationen zu Konvertierungsspezifizierern finden Sie im Abschnitt über den Modulo-Operator.

Aber die Geschichte endet nicht mit dem Modulo-Operator. Später führte Python die Methode str.format() ein:

>>> "Hello, {}! Today is {}.".format(name, day)
'Hello, Pythonista! Today is Friday.'

Die Methode interpoliert ihre Argumente mithilfe von Ersetzungsfeldern, die durch geschweifte Klammern begrenzt sind, in die Zielzeichenfolge. Obwohl diese Methode schwer lesbaren Code erzeugen kann, stellt sie einen erheblichen Fortschritt gegenüber dem Modulo-Operator dar: Sie unterstützt die Minisprache zur Zeichenfolgenformatierung.

Python entwickelt sich ständig weiter und jede neue Version bringt neue, aufregende Funktionen mit sich. Mit Python 3.6 wurden formatierte String-Literale, kurz F-Strings, eingeführt:

>>> f"Hello, {name}! Today is {day}."
'Hello, Pythonista! Today is Friday.'

F-Strings bieten eine besser lesbare und sauberere Möglichkeit, Strings zu erstellen, die andere Strings enthalten. Um einen F-String zu erstellen, müssen Sie ihm ein f oder F voranstellen. Auch hier werden die Ersetzungsfelder durch geschweifte Klammern begrenzt.

F-Strings sind heutzutage wahrscheinlich das beliebteste Interpolationswerkzeug in Python. Sie sind lesbar, schnell zu schreiben und effizient. Sie beginnen also mit F-Strings und erfahren, wie Sie diese verwenden, um mithilfe der Interpolation neue Strings zu erstellen.

Verwenden von F-String-Literalen zum Erstellen von Strings

Für die meisten Interpolationsanwendungsfälle sind F-Strings wahrscheinlich die beste Wahl, wenn Sie Python 3.6 oder höher verwenden. Ihre Syntax ist lesbar und prägnant. Darüber hinaus laufen sie schneller als andere Tools.

Ein Anwendungsfall, bei dem F-Strings nicht die richtige Lösung sind, ist, wenn Sie eine verzögerte Interpolation durchführen müssen. Mit anderen Worten, wenn Sie eine String-Vorlage erstellen und die Komponenten später abhängig von der Codeausführung einfügen müssen. In diesem Fall verwendet Python die Lazy-Option und verzögert die Berechnung des von einem Ausdruck zurückgegebenen Werts, bis dieser Wert benötigt wird.

Ein weiterer zu berücksichtigender Aspekt ist die Sicherheit. Da F-Strings zur Laufzeit ausgewertet werden, könnten sie Ihre Anwendung potenziell Code-Injection-Angriffen aussetzen, wenn Sie die Benutzereingaben vor der Interpolation nicht sorgfältig bereinigen.

In den folgenden Abschnitten erfahren Sie, wie Sie F-Strings für die eifrige String-Interpolation in Python verwenden.

Interpolieren von Werten in F-Strings

Mithilfe von F-Strings können Sie Variablen und Ausdrücke direkt in Ihre Strings interpolieren. Wenn Python dann den F-String ausführt, wird der Inhalt der Variablen oder das Ergebnis des Ausdrucks in das F-String-Literal interpoliert, um den endgültigen String zu erstellen:

>>> x = 5
>>> y = 10

>>> f"The sum of {x} and {y} is {x + y}."
'The sum of 5 and 10 is 15.'

In diesem Beispiel haben Sie zwei Variablen, x und y. Anschließend erstellen Sie ein F-String-Literal mit drei Ersetzungsfeldern. Die ersten beiden Felder enthalten die Variablen und das dritte Feld enthält einen Ausdruck.

Es ist wichtig zu beachten, dass Python F-Strings zur Laufzeit auswertet. In diesem Beispiel werden also x, y und x + y ausgewertet und in das String-Literal interpoliert, wenn Python die Codezeile ausführt enthält den F-String.

Sie können fast jeden Python-Ausdruck in einen F-String einbetten, z. B. arithmetische Ausdrücke, Vergleichsausdrücke und boolesche Ausdrücke. Sie können auch Funktionen und Methodenaufrufe und sogar Comprehensions oder andere komplexere Ausdrücke verwenden:

>>> import math
>>> radius = 16
>>> f"The area of your circle is {math.pi * radius ** 2}"
'The area of your circle is 804.247719318987'

>>> name = "Pythonista"
>>> site = "real python"
>>> f"Hello, {name.upper()}! Welcome to {site.title()}!"
'Hello, PYTHONISTA! Welcome to Real Python!'

>>> f"{[2**n for n in range(3, 9)]}"
'[8, 16, 32, 64, 128, 256]'

Im ersten F-String betten Sie einen mathematischen Ausdruck in das Ersetzungsfeld ein. Im zweiten Beispiel verwenden Sie die String-Methoden .upper() und .title() in den Ersetzungsfeldern. Python wertet den Ausdruck aus und ruft die Methode für Sie auf. Anschließend werden die Ergebnisse in das resultierende F-String-Literal eingefügt. Im letzten Beispiel erstellen Sie einen F-String, der ein Listenverständnis einbettet. Das Verständnis erstellt eine neue Liste von Potenzen von 2.

>>> f"The number is {42}"
'The number is 42'

>>> f"Pi {3.14}"
'Pi 3.14'

In diesen Beispielen interpolieren Sie numerische Werte in Ihren F-String. Python wandelt sie während der Interpolation in String-Objekte um.

Für F-Strings vor Python 3.12 gelten einige Einschränkungen, die Sie bei der Arbeit mit ihnen berücksichtigen müssen. Innerhalb der Ersetzungsfelder ist Folgendes nicht möglich:

  • Verwenden Sie Anführungszeichen oder Zeichenfolgentrennzeichen wieder
  • Betten Sie Backslashes ein, was bedeutet, dass Sie keine Escape-Sequenzen verwenden können
  • Fügen Sie Inline-Kommentare hinzu
  • Verschachteln F-Strings über die verfügbaren Anführungszeichenvarianten hinaus

PEP 536 listet alle diese Einschränkungen auf. Um sie in Aktion zu sehen, lesen Sie den Abschnitt „F-Strings hatten einige Einschränkungen vor Python 3.12“ im Python 3.12-Vorschau-Tutorial.

Selbstdokumentation des interpolierten Werts

Bei F-Strings können Sie eine Funktion namens selbstdokumentierende Ausdrücke verwenden, die nach der interpolierten Variablen oder dem interpolierten Ausdruck ein Gleichheitszeichen hinzufügt. Diese Funktion kann Ihnen beim Debuggen Ihres Codes helfen. Zum schnellen Debuggen verwenden die meisten Benutzer die integrierte Funktion print(), um den Wert einer Variablen oder das Ergebnis eines Ausdrucks zu überprüfen:

>>> value = "Suspicious value"

>>> print(f"{value = }")
variable = 'Suspicious value'

>>> f"{2 + 3 = }"
'2 + 3 = 5'

Sie können eine Variable oder einen Ausdruck gefolgt von einem Gleichheitszeichen (=) in einem F-String verwenden, um einen selbstdokumentierenden Ausdruck zu erstellen. Wenn Python den F-String ausführt, erstellt es einen ausdrucksähnlichen String, der die Variable oder den Ausdruck, das Gleichheitszeichen und das aktuelle Ergebnis enthält.

In diesen Beispielen sind die Leerzeichen um das Gleichheitszeichen nicht erforderlich, sie verbessern jedoch die Lesbarkeit der Ausgabe.

Die Funktion für selbstdokumentierende Ausdrücke erhöht die Lesbarkeit Ihres String-Interpolationsprozesses und kann ein hervorragendes Werkzeug für schnelles Debuggen mit print() sein.

Verwendung unterschiedlicher String-Darstellungen in F-Strings

Mit F-Strings können Sie im Interpolationsprozess zwei Flags mit besonderer Bedeutung verwenden. Diese Flags beziehen sich darauf, wie Python mit der String-Darstellung eines Objekts umgeht. Hier sind die Flaggen und ihre beabsichtigte Bedeutung:

!s

Interpoliert die String-Darstellung mit .__str__()

!r

Interpoliert die String-Darstellung mit .__repr__()

Im Idealfall sollte die spezielle Methode .__str__() eine benutzerfreundliche String-Darstellung eines Objekts bereitstellen. Python greift auf den Aufruf dieser Methode zurück, wenn Sie die Funktion str() verwenden. Unterdessen gibt die Methode .__repr__() eine entwicklerfreundliche Darstellung zurück, die Sie erhalten, wenn Sie die Funktion repr() verwenden.

Um zu veranschaulichen, wie diese Flags funktionieren, betrachten Sie die folgende Beispielklasse:

class Article:
    def __init__(self, title, author, pub_date):
        self.title = title
        self.author = author
        self.pub_date = pub_date

    def __str__(self):
        return (
            f"Article: {self.title}\n"
            f"Author: {self.author}\n"
            f"Published: {self.pub_date}\n"
        )

    def __repr__(self):
        return (
            f"{type(self).__name__}("
            f"title={self.title!r}, "
            f"author={self.author!r}, "
            f"pub_date={self.pub_date!r})"
        )

Diese Article-Klasse verfügt über drei Instanzattribute .title, .author und .pub_date. Die Methode .__str__() gibt eine Zeichenfolge zurück, die die Informationen des Artikels in einem benutzerfreundlichen Format enthält. Diese Nachricht richtet sich eher an Endbenutzer als an Entwickler.

Die Methode .__repr__() gibt einen String zurück, der eine entwicklerfreundliche Darstellung des Objekts ist. Kurz gesagt: Die Darstellung teilt dem Entwickler mit, wie die aktuelle Instanz erstellt wurde. Im Idealfall sollte der Entwickler in der Lage sein, diese Zeichenfolgendarstellung zu kopieren und ein entsprechendes Objekt zu erstellen.

Jetzt ist Ihre Klasse bereit für die Flags !s und !r:

>>> from article import Article

>>> article = Article(
...     title="String Interpolation in Python: Exploring Available Tools",
...     author="Real Python",
...     pub_date="2024-06-03",
... )

>>> print(f"{article!s}")
Article: String Interpolation in Python: Exploring Available Tools
Author: Real Python
Published: 2024-06-03

>>> print(f"{article!r}")
Article(
    title='String Interpolation in Python: Exploring Available Tools',
    author='Real Python',
    pub_date='2024-06-03'
)

Im ersten F-String verwenden Sie das Tag !s, um die String-Darstellung zu interpolieren, die .__str__() zurückgibt. Im zweiten F-String verwenden Sie das Flag !r, um die entwicklerfreundliche String-Darstellung Ihres Objekts zu interpolieren. Beachten Sie, dass im letzteren Fall das resultierende String-Objekt einen gültigen Python-Code darstellt, den Sie auswerten können.

Erstellen von Strings mit der Methode str.format()

Wenn Sie Werte langsam in Zeichenfolgen interpolieren müssen, ist die Methode str.format() genau das Richtige für Sie. Diese Methode ist ein vielseitiges Werkzeug zur String-Interpolation in Python. Es bietet eine lesbare Syntax und ermöglicht sowohl eifrige als auch verzögerte Interpolation.

In den folgenden Abschnitten erfahren Sie, wie Sie die Methode .format() für die Lazy-Interpolation verwenden, da Sie in den meisten Fällen F-Strings für die Eager-Interpolation verwenden würden.

Verwendung von Positionsargumenten und benannten Argumenten

Um Objekte mit der Methode .format() in einen String zu interpolieren, können Sie drei verschiedene Ansätze verwenden. Sie können Folgendes verwenden:

  1. Leere Ersatzfelder, {}
  2. Ersetzungsfelder mit nullbasierten Indizes, {0} ... {n}
  3. Ersetzungsfelder durch benannte Argumente, {arg_1} ... {arg_n}

Um die Funktionsweise dieser Optionen zu veranschaulichen, nehmen wir an, dass Sie den Prozess der E-Mail-Generierung für die Kunden automatisieren müssen, die Produkte Ihres Unternehmens kaufen. Sie können eine E-Mail-Vorlage erstellen und die Kundendaten dann dynamisch interpolieren:

>>> template = """
... Dear {},
...
... Thank you for your recent purchase of {}.
...
... Remember, our support team is always here to assist you.
...
... Best regards,
... {}
... """

>>> print(template.format("Emily", "MacBook Pro 16-inch", "John"))

Dear Emily,

Thank you for your recent purchase of MacBook Pro 16-inch.

Remember, our support team is always here to assist you.

Best regards,
John

In diesem Beispiel erstellen Sie eine E-Mail-Vorlage mit drei leeren Ersetzungsfeldern. Die Methode .format() fügt die übergebenen Werte anhand ihrer relativen Position in das entsprechende Feld ein. Wenn Sie etwas mehr Kontrolle darüber haben möchten, wie die Werte interpoliert werden, können Sie ganzzahlige Indizes verwenden:

>>> template = """
... Dear {0},
...
... Thank you for your recent purchase of {1}.
...
... Remember, our support team is always here to assist you.
...
... Best regards,
... {2}
... """

>>> print(template.format("Linda", "Samsung Galaxy S22", "Jane"))

Dear Linda,

Thank you for your recent purchase of Samsung Galaxy S22.

Remember, our support team is always here to assist you.

Best regards,
Jane

In diesem Beispiel ist das Ergebnis ähnlich. Jetzt sind Sie jedoch sicher, dass das erste Argument, "Linda", zum Index 0 geht, das zweite Argument, "Samsung Galaxy S22" geht zum Index 1 und so weiter. Diese Art der Behandlung der Argumente kann nützlich sein, wenn die ursprüngliche Reihenfolge der Argumente nicht mit der Reihenfolge in der endgültigen Zeichenfolge übereinstimmt:

>>> template = """
... Dear {1},
...
... Thank you for your recent purchase of {0}.
...
... Remember, our support team is always here to assist you.
...
... Best regards,
... {2}
... """

>>> purchase = ("Samsung Galaxy S22", "Linda", "Jane")

>>> print(template.format(*purchase))

Dear Linda,

Thank you for your recent purchase of Samsung Galaxy S22.

Remember, our support team is always here to assist you.

Best regards,
Jane

Hier stimmt die Reihenfolge der Artikel im purchase-Tupel nicht mit der natürlichen Reihenfolge in der Vorlage überein. Sie verschieben also die Indizes entsprechend der neuen Reihenfolge und erhalten das gewünschte Ergebnis.

>>> prefix = "re"
>>> template = "{0}-create and {0}start"

>>> template.format(prefix)
're-create and restart'

In diesem Beispiel verwenden Sie die Variable prefix als Argument für .format(). Wenn Sie den Index 0 zweimal in die Vorlage einfügen, wird auch das Präfix zweimal eingefügt.

Obwohl die oben genannten Optionen einwandfrei funktionieren, sind sie nicht vollständig lesbar. Glücklicherweise gibt es einen besseren Weg. Sie können Schlüsselwortargumente mit .format() verwenden. So geht's:

>>> template = """
... Dear {customer},
...
... Thank you for your recent purchase of {product}.
...
... Remember, our support team is always here to assist you.
...
... Best regards,
... {employee}
... """

>>> print(
...     template.format(
...         customer="Bob",
...         product="Canon EOS R5",
...         employee="Kate"
...     )
... )

Dear Bob,

Thank you for your recent purchase of Canon EOS R5.

Remember, our support team is always here to assist you.

Best regards,
Kate

In diesem Update haben Sie explizite Namen in den Ersetzungsfeldern verwendet. Diese Namen stimmen mit den Schlüsselwortargumenten überein, die Sie beim Aufruf von .format() verwendet haben. Ihr Code sieht jetzt viel besser lesbar aus.

Schließlich ist es auch möglich, Wörterbücher zu verwenden, um die Methode .format() zu füttern. Angenommen, Sie rufen Ihre Daten aus einer CSV-Datei ab, die etwa so aussieht:

product,customer,employee
MacBook Pro 16-inch,Emily,John
Samsung Galaxy S22,Linda,Jane
Canon EOS R5,Bob,Kate

Sie können das Modul csv aus der Standardbibliothek verwenden, um diese Datei zu verarbeiten und ihren Inhalt zu laden, sodass Sie für jeden Verkauf E-Mails erstellen können. Der csv.DictReader ist ein gutes Werkzeug für diese Aufgabe. Mit diesem Reader können Sie jede Zeile einer CSV-Datei in ein Wörterbuch einlesen. Die Schlüssel sind die Dateiüberschriften und die Werte sind die Werte in jeder Zeile.

Hier ist der Code, den Sie für diese Aufgabe verwenden können:

import csv

template = """
Dear {customer},

Thank you for your recent purchase of {product}.

Remember, our support team is always here to assist you.

Best regards,
{employee}
"""

def display_emails(template, path):
    with open(path) as file:
        for customer in csv.DictReader(file):
            print(template.format(**customer))

display_emails(template, "sales.csv")

In diesem Code importieren Sie zunächst csv aus der Standardbibliothek. Dann haben Sie die übliche E-Mail-Vorlage mit Namen in den Ersetzungsfeldern. Die Namen stimmen mit den Überschriften in der CSV-Datei überein.

Als nächstes haben Sie die Funktion display_emails(). Diese Funktion benötigt zwei Argumente: die E-Mail-Vorlage und den Pfad zur CSV-Datei. Innerhalb der Funktion öffnen Sie die Eingabedatei zum Lesen mit einer with-Anweisung.

Die for-Schleife durchläuft mithilfe der Klasse DictReader die Zeilen der Datei. Abschließend verwenden Sie die Methode .format(), um die Werte in der aktuellen Zeile in die E-Mail-Vorlage zu interpolieren. In diesem Beispiel verwenden Sie den Operator zum Entpacken des Wörterbuchs (**), um die Argumente für .format() bereitzustellen.

Fahren Sie fort und führen Sie dieses Skript über Ihre Befehlszeile aus, um die Ausgabe zu überprüfen.

Es gibt ein weiteres interessantes Verhalten von .format(), wenn Sie es mit Wörterbüchern verwenden. Hier ist ein kurzes Spielzeugbeispiel:

>>> numbers = {"one": 1, "two": 2, "three": 3}

>>> "{one}-{two}".format(**numbers)
'1-2'

>>> "{one}-{two}-{three}".format(**numbers)
'1-2-3'

>>> "{one}-{two}-{three}-{four}".format(**numbers)
Traceback (most recent call last):
    ...
KeyError: 'four'

Wenn die Schlüssel im Eingabewörterbuch mit den benannten Argumenten in der Zeichenfolge übereinstimmen, funktioniert die Interpolation auch dann, wenn Sie nicht verwendete Schlüssel haben. Wenn die Schlüssel nicht mit den genannten Argumenten übereinstimmen, erhalten Sie eine KeyError-Ausnahme.

Verwenden unterschiedlicher String-Darstellungen mit .format()

Wie bei F-Strings können Sie auch die Flags !s und !r mit .format() verwenden, um Objekte in Ihre Strings einzufügen verschiedene String-Darstellungen. Hier sind zwei Beispiele, die die Funktionsweise der Flags zeigen, indem wir die Klasse Article aus dem Abschnitt „Verwenden unterschiedlicher String-Darstellungen in F-Strings“ wiederverwenden:

>>> from article import Article

>>> article = Article(
...     title="String Interpolation in Python: Exploring Available Tools",
...     author="Real Python",
...     pub_date="2024-06-03",
... )

>>> print("{article!s}".format(article=article))
Article: String Interpolation in Python: Exploring Available Tools
Author: Real Python
Published: 2024-06-03

>>> print("{article!r}".format(article=article))
Article(
    title='String Interpolation in Python: Exploring Available Tools',
    author='Real Python',
    pub_date='2024-06-03'
)

Auch hier ermöglicht Ihnen das Flag !s die Verwendung der benutzerfreundlichen String-Darstellung des jeweiligen Objekts. Im Gegensatz dazu ermöglicht Ihnen das Flag !r die Verwendung der entwicklerfreundlichen Darstellung. Sie entscheiden, welches Flag Sie in Ihrem Code verwenden möchten, indem Sie die Zielgruppe Ihres Codes berücksichtigen.

Verwendung des Modulo-Operators (%) für die Interpolation

Die Verwendung des Modulo-Operators (%) zur String-Interpolation ist im modernen Python weitgehend veraltet. Dieses Tool funktioniert jedoch weiterhin und Sie werden wahrscheinlich älteren Code finden, der es verwendet. Daher ist es gut zu wissen, wie es funktioniert.

Der Modulo-Operator (%) ist das älteste Werkzeug zur Durchführung der String-Interpolation in Python. Obwohl Sie diesen Operator sowohl für die Eager- als auch für die Lazy-String-Interpolation verwenden können, könnte die Syntax lesbarer und sauberer sein.

Sie müssen Konvertierungsspezifizierer in Ihre Zeichenfolgen einfügen und dann den Modulo-Operator verwenden, um die gewünschten Werte zu interpolieren:

>>> x = 5
>>> y = 10

>>> "The sum of %d and %d is %d." % (x, y, x + y)
'The sum of 5 and 10 is 15.'

Eine Kombination von Zeichen, die mit dem Prozentzeichen (%) beginnen, wird als Konvertierungsspezifizierer bezeichnet. In diesem Beispiel haben Sie den Spezifizierer %d verwendet, was bedeutet, dass Sie einen vorzeichenbehafteten ganzzahligen Dezimalwert in eine Zeichenfolge konvertieren möchten. Die Konvertierungsspezifizierer dienen als Ersatzfelder für den Modulo-Operator.

>>> name = b"Pythonista"

>>> b"Hello, %b!" % name
b'Hello, Pythonista!'

Sie können diese Art der Interpolation nicht mit F-Strings durchführen, da die Syntax fb"" oder bf"" nicht gültig ist. Die Methode .format() lässt diese Art der Interpolation nicht zu, da bytes-Objekte diese Methode nicht haben.

Um eine verzögerte Interpolation durchzuführen, können Sie etwa Folgendes tun:

>>> template = "The sum of %d and %d is %d."

>>> template % (x, y, x + y)
'The sum of 5 and 10 is 15.'

In diesem Beispiel erstellen Sie eine Vorlagenzeichenfolge mit den erforderlichen Ersetzungsfeldern. Anschließend verwenden Sie den Modulo-Operator, um später in Ihrem Code Werte in die Vorlage zu interpolieren. Mit dieser Vorgehensweise können Sie die Vorlagenzeichenfolge in verschiedenen Teilen Ihres Codes wiederverwenden.

Dann haben Sie den Modulo-Operator und ein Tupel von Werten oder Ausdrücken. Der Operator interpoliert jeden Wert in diesem Tupel anhand seiner Position in den entsprechenden Bezeichner.

Interpolieren eines oder mehrerer Werte

Im vorherigen Abschnitt haben Sie ein Beispiel gesehen, in dem Sie mehrere Werte oder Ausdrücke mithilfe des Modulo-Operators in eine Zeichenfolge interpoliert haben. Wenn Sie nur einen Wert einfügen müssen, können Sie das Tupel überspringen oder ein Tupel mit einem einzelnen Element verwenden:

>>> "Hello, %s!" % "Pythonista"
'Hello, Pythonista!'

>>> "Hello, %s!" % ("Pythonista",)
'Hello, Pythonista!'

Die erste Syntax ist etwas sauberer als die zweite Syntax. Aus Gründen der Konsistenz im gesamten Code möchten Sie jedoch möglicherweise die zweite Syntax verwenden.

Was passiert nun, wenn Sie ein Tupelobjekt interpolieren müssen? Hier ist ein Beispiel:

>>> "Interpolating a tuple: %s" % (1, 2, 3)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    "Interpolating a tuple: %s" % (1, 2, 3)
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
TypeError: not all arguments converted during string formatting

In diesem Beispiel interpretiert Python das Tupel als drei verschiedene Werte und Sie erhalten eine Fehlermeldung, da die Zeichenfolge nur ein Ersetzungsfeld enthält. Um dieses Problem zu umgehen, müssen Sie ein Tupel mit einem einzelnen Element verwenden:

>>> "Interpolating a tuple: %s" % ((1, 2, 3),)
'Interpolating a tuple: (1, 2, 3)'

Jetzt funktioniert die Interpolation korrekt und am Ende wird das Tupel in die Zeichenfolge eingefügt. Es ist wichtig zu beachten, dass Sie Tupel verwenden müssen, wenn Sie mehrere Werte in den Modulo-Operator eingeben möchten:

>>> "Hello, %s! Today is %s." % [name, day]
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    "Hello, %s! Today is %s." % [name, day]
     ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
TypeError: not enough arguments for format string

>>> "The sum of %d and %d is %d." % [x, y, x + y]
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    "The sum of %d and %d is %d." % [x, y, x + y]
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
TypeError: %d format: a real number is required, not list

Wenn Sie ein list-Objekt oder ein anderes iterierbares Objekt verwenden, interpretiert Python es als einzelnes Objekt und die Interpolation schlägt mit einer TypeError-Ausnahme fehl.

Benannte Ersetzungsfelder verwenden

Im vorherigen Abschnitt haben Sie erfahren, dass Sie ein Tupel verwenden sollten, um dem Modulo-Operator für die String-Interpolation mehrere Argumente bereitzustellen. Auf diese Weise fügt der Operator die Werte im Tupel entsprechend ihrer Position in die Zielzeichenfolge ein, diese ist jedoch nicht so gut lesbar.

Glücklicherweise gibt es einen besseren Weg. Sie können auch Wörterbücher und benannte Ersetzungsfelder verwenden:

>>> jane = {"name": "Jane", "job": "Python Dev"}

>>> "My name is %(name)s. I'm a %(job)s." % jane
"My name is Jane. I'm a Python Dev."

In diesem Beispiel fügt der Modulo-Operator jeden Wert mit dem entsprechenden Schlüssel ein, was viel lesbarer und intuitiver ist. Um die benannten Ersetzungsfelder zu erstellen, müssen Sie den Namen in Klammern zwischen dem %-Zeichen und dem Formatbezeichner einfügen.

Verwendung unterschiedlicher String-Darstellungen

Sie können die unterschiedlichen String-Darstellungen von Objekten auch mit dem Modulo-Operator zur String-Interpolation verwenden. Sie haben bereits erfahren, dass der Konvertierungsspezifizierer %s das Objekt in Zeichenfolgen konvertiert. Dazu verwendet der Spezifizierer die benutzerfreundliche Darstellung der speziellen Methode .__str__().

Um die entwicklerfreundliche Zeichenfolgendarstellung zu verwenden, die in .__repr__() bereitgestellt wird, können Sie den Konvertierungsspezifizierer %r verwenden.

Um dies zu veranschaulichen, können Sie erneut die Klasse Article verwenden:

>>> from article import Article

>>> article = Article(
...     title="String Interpolation in Python: Exploring Available Tools",
...     author="Real Python",
...     pub_date="2024-06-03",
... )

>>> print("%s" % article)
Article: String Interpolation in Python: Exploring Available Tools
Author: Real Python
Published: 2024-06-03

>>> print("%r" % article)
Article(
    title='String Interpolation in Python: Exploring Available Tools',
    author='Real Python',
    pub_date='2024-06-03'
)

Das resultierende Verhalten ist das gleiche wie bei F-Strings und der Methode .format(). Auch hier hängt die Wahl der zu verwendenden Zeichenfolgendarstellung von der Zielgruppe Ihres Codes ab.

Verwendung von F-Strings vs. .format() vs. %

Bisher haben Sie drei verschiedene Python-Tools kennengelernt, die Sie für die String-Interpolation verwenden können. Eine Frage, die sich stellen kann, ist: Welches Tool sollten Sie verwenden? Wie bei vielen Dingen lautet die Antwort: Es kommt darauf an.

Wenn Sie eine lesbare Syntax und eine gute Leistung bei der String-Interpolation wünschen und nur Eager-Interpolation durchführen, dann sind F-Strings das Richtige für Sie. Wenn Sie ein Tool für die verzögerte String-Interpolation benötigen, ist die Methode .format() die richtige Wahl.

Im Gegensatz dazu ist der Modulo-Operator (%) ein altmodisches Werkzeug, das im modernen Python nicht häufig verwendet wird. Man könnte sagen, dass dieses Tool fast tot ist. Möglicherweise finden Sie es jedoch in älterem Python-Code, daher ist es gut zu lernen, wie es funktioniert.

In der folgenden Tabelle werden die drei Tools anhand mehrerer Vergleichskriterien verglichen:

Feature F-strings .format() %
Readability High Medium Low
Supports lazy evaluation ⛔️
Supports dictionary unpacking ⛔️
Supports the format mini-language ⛔️

F-Saiten sind in puncto Lesbarkeit der klare Gewinner. Sie erlauben jedoch keine verzögerte Interpolation. Es gibt keine Möglichkeit, mit einem F-String eine wiederverwendbare String-Vorlage zu erstellen, die Sie später in Ihrem Code interpolieren können.

Darüber hinaus können Sie ein Wörterbuch nicht verwenden, um die Eingabewerte auf einmal bereitzustellen. Das bedeutet nicht, dass Sie Wörterbuchschlüssel nicht in einen F-String interpolieren können:

>>> numbers = {"one": 1, "two": 2, "three": 3}

>>> f"{numbers['one']}-{numbers['two']}-{numbers['three']}"
'1-2-3'

Um Wörterbuchschlüssel in einen F-String zu interpolieren, müssen Sie den Schlüssel in das gewünschte Ersetzungsfeld einfügen. Dies kann dazu führen, dass Ihre F-Saite unübersichtlich aussieht und schwer zu lesen und zu schreiben ist. In solchen Fällen ist es besser, die Methode .format() zu verwenden:

>>> "{one}-{two}-{three}".format(**numbers)
'1-2-3'

>>> "{one}-{two}".format(**numbers)
'1-2'

Dieser Code ist viel besser lesbar und schneller zu schreiben als die F-String-Version. Ein zusätzlicher Vorteil besteht darin, dass die Anzahl der Schlüssel im Eingabewörterbuch nicht mit der Anzahl der Ersetzungsfelder in der Vorlagenzeichenfolge übereinstimmen muss, wodurch der Code flexibler und allgemeiner wird.

Schließlich unterstützen sowohl F-Strings als auch die Methode .format() die Python-Minisprache zur Zeichenfolgenformatierung, mit der Sie die interpolierten Werte gut formatieren können. Als kurzes Beispiel sehen Sie hier, wie Sie die π-Konstante mit vier Dezimalstellen formatieren können:

>>> import math
>>> math.pi
3.141592653589793

>>> f"{math.pi:.4f}"
'3.1416'

>>> "{pi:.4f}".format(pi=math.pi)
'3.1416'

Das Formatieren interpolierter Werte mit der Formatierungs-Minisprache geht über den Rahmen dieses Tutorials hinaus. Wenn Sie dieses Thema weiter vertiefen möchten, schauen Sie sich das Tutorial „Python’s Format Mini-Language for Tidy Strings“ an.

Erstellen von Vorlagen mit der Klasse Template

Python verfügt über ein weiteres Tool zur Durchführung der String-Interpolation. Im Modul string finden Sie die Klasse Template. Wie der Name schon sagt, können Sie mit dieser Klasse String-Vorlagen erstellen, die Sie für die verzögerte Interpolation verwenden können.

Sie werden zwei Hauptunterschiede zwischen Template und Standard-String-Interpolationstools feststellen. Bei Template wird der Typ der interpolierten Werte nicht berücksichtigt. Die Werte werden automatisch in Strings umgewandelt und dann in die Vorlage eingefügt.

Außerdem unterstützt Template keine Zeichenfolgenformatierung. Andererseits haben die Standardtools den Vorteil, dass sie die Minisprache zur Zeichenfolgenformatierung unterstützen, die Ihnen bei der Feinabstimmung Ihrer Zeichenfolgen hilft.

Um einen Vorlagenstring mit Template zu erstellen, benötigen Sie einen regulären Python-String mit eingebetteten Platzhaltern. Diese Platzhalter bestehen aus zwei Teilen:

  1. Das Dollarzeichen ($)
  2. Ein gültiger Python-Bezeichner

Gültige Bezeichner sind solche, die Sie in Python als Variablennamen verwenden können. Sie kombinieren Groß- und Kleinbuchstaben, Unterstriche (_) und Ziffern. Bezeichner dürfen nicht mit Ziffern beginnen oder mit einem Python-Schlüsselwort übereinstimmen. Zum Beispiel $name, $age, $Tag, $class_ und $item_1 sind allesamt gültige Platzhalter.

Nachdem Sie die Zeichenfolge mit den entsprechenden Platzhaltern erstellt haben, müssen Sie Folgendes tun:

  1. Importieren Sie Template aus dem Modul string
  2. Instanziieren Sie Template mit der Vorlagenzeichenfolge als Argument
  3. Führen Sie die Ersetzung mit einer von zwei relevanten Methoden durch

Hier ist ein kurzes Beispiel dafür, wie Sie Template in Ihrem Code verwenden können:

>>> from string import Template

>>> template = Template("Hello, $name! Today is $day.")
>>> template.substitute(name="John", day="Friday")
'Hello, John! Today is Friday.'

In diesem Beispiel verwenden Sie eine Vorlagenzeichenfolge mit zwei Platzhaltern, $name und $day, als Argument für Template. Sobald Sie die Klasse instanziiert haben, können Sie .substitute() aufrufen, um Werte zu interpolieren. Beachten Sie, dass die Namen der Argumente, die Sie an .substitute() übergeben, mit den Bezeichnern übereinstimmen müssen, die in den Platzhaltern Ihrer Vorlagenzeichenfolge verwendet werden.

In den folgenden Abschnitten erfahren Sie mehr über das Erstellen von Vorlagenzeichenfolgen mit der Klasse Template.

Erstellen von Vorlagenzeichenfolgen

Um gültige Vorlagenzeichenfolgen zu erstellen, die Sie der Klasse Template zuführen können, beachten Sie einige Grundregeln. So beschreibt PEP 292 diese Regeln:

  1. $$ ist ein Escape; es wird durch einen einzelnen $ ersetzt
  2. $identifier benennt einen Substitutionsplatzhalter, der mit dem Zuordnungsschlüssel „identifier“ übereinstimmt. Standardmäßig muss „Bezeichner“ einen Python-Bezeichner buchstabieren, wie in [2] definiert. Das erste Nicht-Bezeichnerzeichen nach dem Zeichen $ beendet diese Platzhalterspezifikation.
  3. $ {identifier} entspricht $identifier. Dies ist erforderlich, wenn gültige Identifikationszeichen dem Platzhalter folgen, aber nicht Teil des Platzhalters sind, z. B. "$ {noun}ification". (Quelle)

Zum Auftakt beginnen Sie mit einem Beispiel, wie Sie das Dollarzeichen ($) maskieren können, das zum Ausdrücken von Währungswerten erforderlich ist, zum Beispiel:

>>> from string import Template

>>> Template("$$$amount").substitute(amount="1,000.00")
'$1,000.00'

In dieser Zeichenfolgenvorlage maskieren die ersten beiden Dollarzeichen das erforderliche Dollarzeichen und das letzte Dollarzeichen definiert den Platzhalter.

Die zweite Regel besagt, dass jeder Platzhalter ein $-Zeichen gefolgt von einem gültigen Python-Bezeichner benötigt. Hier ist ein Beispiel:

>>> Template("$greeting, $who!").substitute(greeting="Hello", who="World")
'Hello, World!'

In diesem Beispiel bilden Sie die Platzhalter mithilfe der gültigen Python-Bezeichner greeting und who. Wie die zweite Regel besagt, beendet das erste Nicht-Bezeichnerzeichen den Platzhalter. Dies gilt also für das Komma nach $greeting und das Ausrufezeichen nach $who.

Die dritte Regel gilt für Situationen, in denen Sie ein Wort in einer Zeichenfolge ersetzen müssen und die Zeichen, die auf den Bezeichner folgen, für Gebäudebezeichner gültig sind. In dieser Situation weiß Python nicht, wo der Bezeichner endet.

Angenommen, Sie benötigen eine Vorlage, mit der Sie einen Geldbetrag in USD anzeigen können. In dieser Situation können Sie etwa Folgendes tun:

>>> Template("${amount}USD").substitute(amount="100")
'100USD'

>>> Template("$amountUSD").substitute(amount="100")
Traceback (most recent call last):
    ...
KeyError: 'amountUSD'

Da es sich bei USD um alle Zeichen handelt, die Sie in einem gültigen Python-Bezeichner verwenden können, müssen Sie den Platzhalterstil $ {identifier verwenden. Andernfalls erhalten Sie einen KeyError.

Schließlich wird die Vorlagenzeichenfolge, die Sie dem Konstruktor Template() bereitstellen, im Attribut .template gespeichert. Dadurch können Sie die Vorlage dynamisch ändern:

>>> greeting = Template("Hello, $name! Today is $day.")
>>> greeting.substitute(name="John", day="Friday")
'Hello, John! Today is Friday.'

>>> greeting.template = "Hello, $name! Welcome!"
>>> greeting.substitute(name="John")
'Hello, John! Welcome!'

Sie können das Attribut .template jederzeit ändern. Es ist jedoch am besten, für jede unterschiedliche Vorlagenzeichenfolge in Ihrem Code neue Instanzen von Template zu erstellen. Auf diese Weise verhindern Sie, dass subtile Fehler auftreten oder Ihre Vorlagen beschädigt werden.

Ersetzen von Werten mit .substitute()

Bisher haben Sie die Methode .substitute() mit Schlüsselwortargumenten verwendet, um Werte in Ihren String-Vorlagen zu interpolieren. Sie können die Methoden auch mit Wörterbüchern verwenden:

>>> from string import Template

>>> numbers = {"one": 1, "two": 2, "three": 3}

>>> Template("$one-$two-$three").substitute(**numbers)
'1-2-3'

Auch hier gilt: Wenn Sie ein Wörterbuch als Argument für substitute() verwenden, müssen Sie den Operator zum Entpacken des Wörterbuchs (**) verwenden. Dieser Operator entpackt die Schlüssel-Wert-Paare in Schlüsselwortargumente, die in die entsprechenden Platzhalter in der Vorlagenzeichenfolge eingefügt werden.

Beachten Sie, dass die Platzhalternamen mit den Wörterbuchschlüsseln übereinstimmen müssen. Wenn ein Platzhalter mit keinem Schlüssel übereinstimmt oder wenn die Anzahl der Schlüssel nicht mit der Anzahl der Platzhalter übereinstimmt, erhalten Sie eine Fehlermeldung:

>>> numbers = {"one": 1, "two": 2}

>>> Template("$one-$two-$three").substitute(**numbers)
Traceback (most recent call last):
    ...
KeyError: 'three'

Wenn Sie .substitute() mit einem Wörterbuch aufrufen, dessen Schlüssel nicht mit allen Platzhaltern in der Vorlagenzeichenfolge übereinstimmen, erhalten Sie einen KeyError.

Ersetzen von Werten mit .safe_substitute()

Template verfügt über eine weitere Methode, mit der Sie die Werte in die String-Vorlage interpolieren können. Die Methode heißt .safe_substitute() und funktioniert ähnlich wie .substitute(). Wenn Sie jedoch einen unvollständigen oder nicht übereinstimmenden Satz von Argumenten verwenden, löst die Methode keinen KeyError aus:

>>> from string import Template

>>> numbers = {"one": 1, "two": 2}

>>> Template("$one-$two-$three").safe_substitute(**numbers)
'1-2-$three'

In diesem Codeausschnitt rufen Sie .safe_substitute() mithilfe eines Wörterbuchs auf, dessen Schlüssel nicht mit allen vorhandenen Platzhaltern übereinstimmen. Anstatt eine KeyError-Ausnahme zu erhalten, erhalten Sie eine Zeichenfolge, die den fehlenden Platzhalter buchstäblich anzeigt. Dies kann hilfreich sein, um die fehlenden Werte in einer Ansicht einer zu rendernden HTML-Seite zu identifizieren.

Die Methode .safe_substitute() könnte ein Vorteil der Verwendung von Template gegenüber der Methode .format() sein:

>>> "{one}-{two}-{three}".format(**numbers)
Traceback (most recent call last):
    ...
KeyError: 'three'

Die Methode .format() bietet keine sichere Möglichkeit, die Interpolation durchzuführen, wenn Sie einen unvollständigen oder nicht übereinstimmenden Satz von Argumenten verwenden.

Abschluss

Sie haben gelernt, wie Sie eine String-Interpolation durchführen und neue Strings erstellen, indem Sie Objekte in eine String-Vorlage einfügen. Jetzt wissen Sie, dass Python über mehrere Tools zur String-Interpolation verfügt. Zu diesen Tools gehören F-Strings, die Methode str.format() und der Modulo-Operator (%).

Sie haben auch etwas über die Klasse Template gelernt, die Sie auch für die String-Interpolation verwenden können. Diese Klasse ist in einem Standardbibliotheksmodul namens string enthalten.

In diesem Tutorial haben Sie:

  • Erfahren Sie, wie Sie f-strings für die eifrige String-Interpolation verwenden
  • Lazy String-Interpolation mit str.format() durchgeführt
  • Verwendet den Modulo-Operator (%) für die String-Interpolation
  • Erfahren Sie, wann Sie f-strings oder str.format() für die Interpolation verwenden sollten
  • String-Interpolation mit der Klasse string.Template durchgeführt

Jetzt verfügen Sie über die erforderlichen Kenntnisse, um mit der Erstellung von Zeichenfolgen mithilfe verschiedener Interpolationswerkzeuge zu beginnen. Welches Tool Sie verwenden, hängt von Ihrem spezifischen Anwendungsfall ab.