String-Formatierung ist der Prozess, Werte in Strings umzuwandeln und sie in eine String-Vorlage einzufügen. Der Zen of Python behauptet, es solle „einen offensichtlichen Weg geben, etwas in Python zu tun". Doch wenn es um String-Formatierung geht, ist die Sache etwas ... weniger zen.
Es mag überraschen, dass es in Python vier Hauptwege gibt, Strings zu formatieren, jeden für ein anderes Szenario.
Einiges davon liegt an Pythons langer Geschichte, anderes an Überlegungen wie Internationalisierung oder der Bereinigung von Eingaben.
Wir beginnen mit den neuesten Ergänzungen im Werkzeugkasten der String-Formatierung und arbeiten uns rückwärts bis zur Formatierung im „alten Stil" oder im „printf()-Stil" vor.
f-string
Eingeführt in Python 3.6, sind f-strings (kurz für „formatted strings") oder literale String-Interpolation eine Möglichkeit, Ausdrücke und Strings schnell und effizient auszuwerten (und zu formatieren) und in den Typ str umzuwandeln, indem man das Präfix f (oder F) vor die Anführungszeichen setzt (so: f'{object}').
f-strings lassen sich mit allen umschließenden String-Typen verwenden, etwa einzeilig (' oder ") und mehrzeilig (''' oder """).
Alle Variablen, Ausdrücke oder anderen Typen, die in die {} gesetzt werden, werden zuerst ausgewertet, dann in einen str umgewandelt und schließlich mit allen strs außerhalb der geschweiften Klammern verkettet.
In diesem Beispiel setzen wir zwei Variablenwerte in einen Satz ein (ein str und ein float):
>>> name = 'eighth'
>>> value = 1/8
# The f-string, using the two values.
# The .2f format code truncates, so the value displays as 0.12.
>>> f'An {name} is approximately {value:.2f}.'
'An eighth is approximately 0.12.'
Die ausgewerteten Ausdrücke können fast alles sein.
Einige der (breiten Palette an) Möglichkeiten, die ausgewertet werden können: strs, Zahlen, Variablen, arithmetische Ausdrücke, bedingte Ausdrücke, eingebaute Typen, Slices, Funktionen, Lambdas, Comprehensions oder beliebige Objekte, für die entweder __str__- oder __repr__-Methoden definiert sind.
Von einfach zu komplex:
Eine Variable einfügen: Die einfachste Verwendung eines f-strings besteht darin, eine Variable direkt in den String zu setzen.
# Assigning a variable.
>>> name = "World"
# Inserting that variable.
>>> f'Hello, {name}!'
'Hello, World!'
Ausdrücke innerhalb von {}: Jeder gültige Python-Ausdruck kann innerhalb der geschweiften Klammern ausgewertet werden.
Beachte, dass doppelte Anführungszeichen innerhalb eines f-strings in einfachen Anführungszeichen (oder umgekehrt) Escape-Sequenzen überflüssig machen:
# A dictionary of key:value pairs.
>>> waves = {'water': 1, 'light': 3, 'sound': 5}
# Inserting the whole dict.
>>> f'Wave ranks: {waves}'
"Wave ranks: {'water': 1, 'light': 3, 'sound': 5}"
# An expression can be evaluated inline:
>>> f"Tenfold the value of 'light' is {waves['light'] * 10}."
"Tenfold the value of 'light' is 30."
# A method call can also be evaluated inline:
>>> f'{"hello world!".title()} is a classic greeting.'
'Hello World! is a classic greeting.'
# An f-string can be nested inside another f-string:
>>> f"{f'hello world!'.title()} is a classic greeting."
'Hello World! is a classic greeting.'
Ausgabeformatierung: Mit der Mini-Sprache für Formatangaben lassen sich Ausrichtung, numerische Genauigkeit und vieles mehr steuern.
Die Formatangabe steht nach dem Wert und wird durch ein : getrennt.
# Right-align a value to ten characters, and round it to 3 decimal places.
>>> value = 1 / 7
>>> f'One seventh is {value:10.3f}.'
'One seventh is 0.143.'
# A format specification can be set using variables as well.
>>> padding = 10
>>> precision = 3
>>> f'One seventh is {value:{padding}.{precision}f}.'
'One seventh is 0.143.'
Alles zusammen: Variablen, Ausdrücke, Funktionsaufrufe und Ausgabeformatierung:
>>> precision = 3
>>> f"{30e8 * 111_000:6.{precision}e}"
'3.330e+14'
>>> verb = 'meet'
>>> the_end = ['end', 'of', 'transmission']
>>> f'"Have a {"NICE".lower()} day, I will {verb} you after {30e8 * 111_000:6.{precision}e} light-years."{the_end}'
'"Have a nice day, I will meet you after 3.330e+14 light-years."[\'end\', \'of\', \'transmission\']'
# Did you notice the escaped single-quotes in the previous example?
# Using double quotes instead of single quotes for the f-string means the list's single-quoted strings print cleanly.
>>> f"Have a nice day. {the_end}"
"Have a nice day. ['end', 'of', 'transmission']"
Es gibt zwei wichtige Einschränkungen, die du kennen solltest.
f-string-Ausdrücke dürfen nicht leer sein.
Außerdem durften sie vor Python 3.12 keine Kommentare enthalten.
>>> f"An empty expression will error: {}"
SyntaxError: f-string: empty expression not allowed
>>> word = 'word'
>>> f"""A comment in a triple quoted f-string: {
word # I chose a nice variable
}"""
'A comment in a triple quoted f-string: word'
String-Interpolation kann nicht zusammen mit der GNU-gettext-API für Internationalisierung (I18N) und Lokalisierung (L10N) verwendet werden. Deshalb empfiehlt es sich, in Übersetzungsszenarien mit „String-Wrapping" die Klasse string.Template oder die weiter unten beschriebene Methode str.format() anstelle eines f-strings zu verwenden.
Beachte außerdem, dass die Verwendung von Ausdrücken innerhalb der f-string-Klammern {} dem Einsatz von eval() oder exec() ähnelt. Sie ist daher nicht sehr sicher und sollte niemals mit Benutzereingaben verwendet werden.
str.format()
Die Methode str.format() ersetzt Platzhalter innerhalb des Strings durch Werte, die als Argumente an die Funktion übergeben werden.
Die Platzhalter werden durch Namen ({price}), Zahlen ({0} oder Indizes) oder sogar leere (positionsbezogene) Platzhalter {} gekennzeichnet.
Zum Beispiel:
# A named placeholder and a positional placeholder.
>>> 'My text: {placeholder_1} and {}.'.format(12, placeholder_1='named placeholder')
'My text: named placeholder and 12.'
Wie bei f-strings unterstützt Pythons str.format() eine ganze Reihe von Formatbezeichnern der Mini-Sprache, mit denen sich Text ausrichten, Gleitkommazahlen abschneiden und mehr machen lässt.
Das vollständige Muster eines Formatbezeichners lautet {[<name>][!<conversion>][:<format_specifier>]}:
<name> kann ein benannter Platzhalter, eine Zahl oder leer sein.!<conversion> ist optional und sollte eine dieser drei Konvertierungen sein: !s für str(), !r für repr() oder !a für ascii().
Standardmäßig wird str() verwendet.:<format_specifier> ist optional und steuert, wie der Wert dargestellt wird.
Weitere Informationen zu den möglichen Optionen findest du hier.Beispiel für Konvertierungen bei einem Buchstaben mit diakritischem Zeichen:
# Fills in the object at index zero, converted to a string.
>>> 'An e with an umlaut: {0!s}'.format('ë')
'An e with an umlaut: ë'
# Fills in the object at index zero, converted to a repr.
>>> 'An e with an umlaut (object representation): {0!r}'.format('ë')
"An e with an umlaut (object representation): 'ë'"
# Fills in the object at index zero, converted to ASCII.
>>> 'An e with an umlaut converted into ASCII: {0!a}'.format('ë')
"An e with an umlaut converted into ASCII: '\xeb'"
# Fills in the object in the first position,
# then fills in the object in the second position formatted as a repr.
>>> 'She said her name is not {} but {!r}.'.format('Chloe', 'Zoë')
"She said her name is not Chloe but 'Zoë'."
Beispiele für gängige Formatbezeichner:
# Integer and binary/hex representations of the same number.
>>> my_num = 42
>>> f"{my_num} in binary is {my_num:b}. In hex, it is {my_num:x}"
"42 in binary is 101010. In hex, it is 2a"
# Alignment: left (<), right (>), and center (^) using up to ten characters total.
>>> f"[{"left":<10}] [{"right":>10}] [{"center":^10}]"
"[left ] [ right] [ center ]"
# Float precision and scientific notation (up to three decimal places).
>>> pi = 3.141592653589793
>>> f"Fixed: {pi:.3} Scientific: {pi:.3e}"
"Fixed: 3.142 Scientific: 3.142e+00"
# Thousands separator and percentage.
>>> balance = 1000
>>> rate = 0.0225
>>> f"Balance: ${balance:,.0f} Interest rate: {rate:.1%}"
"Balance: $1,000 Interest rate: 2.2%"
# Putting it all together:
>>> items = [("Widget", 1250, 9.991), ("Gadget", 37, 24.503), ("Doohickey", 4, 149.002)]
>>> header = f"{"Item":<12} {"Qty":>6} {"Price":>9}"
>>> print(header)
Item Qty Price
>>> for name, qty, price in items:
... print(f"{name:<12} {qty:>6} {price:>9.2f}")
Widget 1250 9.99
Gadget 37 24.50
Doohickey 4 149.00
Weitere Beispiele findest du am Ende dieser Dokumentation.
%-Formatierung oder Formatierung im printf()-StilDie Verwendung des %-Operators zum Formatieren ist die älteste Methode der String-Formatierung in Python.
Sie stammt aus der Sprache C und erlaubt es, mit positionsbezogenen Argumenten einen str aufzubauen.
Diese Methode wurde sowohl von f-strings als auch von str.format() abgelöst. Daher lautet der Spitzname für die %-Formatierung "Old Style".
Sie findet sich noch in Python 2 und/oder in Legacy-Code.
Zwar funktioniert diese Methode in Python 3.x, doch die %-Formatierung wird meist gemieden, weil sie fehleranfällig sein kann, weniger effizient ist, weniger Optionen bietet und jede Nichtübereinstimmung zwischen Platzhalter und Argument eine Ausnahme auslösen kann.
Die Verwendung des %-Operators ähnelt printf(), weshalb sie manchmal auch printf-Formatierung genannt wird.
# Assigning a variable.
>>> name = "Anna-conda"
# Building a string using %.
>>> "The snake's name is %s." % name
"The snake's name is Anna-conda."
Im obigen Beispiel ersetzt der %-Operator zur Laufzeit den Platzhalter %s durch die Variable name.
Wenn du mehrere Variablen zu einem String hinzufügen möchtest, musst du nach dem % ein Tupel angeben, das ein Objekt pro Platzhalter enthält:
# Assigning variables.
>>> name = "Billy the Kid"
>>> fruit = "grapes"
# Building a string using %.
>>> "Surprisingly, %s's favorite snack was %s." %(name, fruit)
"Surprisingly, Billy the Kid's favorite snack was grapes."
string.Template() (nicht zu verwechseln mit den t-strings aus Python 3.14) ist eine Klasse aus dem Modul string (im Gegensatz zum eingebauten Typ str), die Teil der Python-Standardbibliothek ist, aber zur Verwendung importiert werden muss.
Template-Strings unterstützen die Ersetzung mit $ und sind viel einfacher und weniger mächtig als die anderen hier genannten Möglichkeiten.
Sie können jedoch sehr nützlich für komplizierte Internationalisierung oder für die Bereinigung externer Eingaben sein.
string.Template gilt als sicherer für nicht vertrauenswürdige Benutzereingaben, weil es verhindert, dass beliebige Ausdrücke ausgewertet oder auf Objektattribute zugegriffen wird, was Format-String-Injection-Angriffe abschwächt.
>>> from string import Template
>>> name = "Anna-Conda"
# Creating a Template with placeholder text.
>>> template_string = Template("The snake called `$snake_name` has escaped!")
# Calling .substitute() to replace the placeholder with a value.
>>> template_string.substitute(snake_name=name)
'The snake called `Anna-Conda` has escaped!'
Weitere Informationen zu string.Template findest du in der Python-Dokumentation.
Bei all diesen Optionen und Mini-Sprachen: Wie entscheidest du, zu welcher du greifst, wenn du Python-Strings formatierst? Hier sind ein paar kurze Richtlinien:
f-strings sind die neuesten und am einfachsten zu lesen.
Wenn du nicht internationalisieren musst, sollten sie ab Python 3.6 die bevorzugte Methode sein.
str.format() ist vielseitig, mächtig und sowohl mit gnu gettext als auch mit den meisten Python-Versionen kompatibel.
Wenn du Einfachheit, Sicherheit und/oder umfangreiche Internationalisierung brauchst, kannst du string.Template() verwenden, um Risiken beim Umgang mit Benutzereingaben zu verringern und um Übersetzungsstrings zu umhüllen.
Der %-Operator gilt für neuen Code allgemein als veraltet, funktioniert aber in modernem Python noch.
Du solltest ihn hauptsächlich für die Kompatibilität mit älteren Codebasen verwenden.
Die %-Formatierung ist fehleranfälliger (und hat weniger Funktionalität) als andere Methoden und kann zu Problemen bei der Anzeige von Nicht-ASCII-Zeichen führen.
Prüfe deine spezifische Python-Distribution auf Support-Details, wenn du ihn verwenden möchtest.
Wenn du weiter gehen möchtest, sind Alles über Formatierung und Python String Formatting Best Practices gute Ausgangspunkte.