Python String-Formatierung
Alle drei Python-Formatierungsmethoden im Überblick: %-Operator, str.format() und f-Strings — mit Beispielen für Zahlen, Ausrichtung, Daten und mehr.
Die String-Formatierung ermöglicht es, Zeichenketten dynamisch aufzubauen, indem Variablen, Ausdrücke und berechnete Werte in eine Vorlage eingefügt werden. Python bietet drei verschiedene Ansätze — den veralteten %-Operator, die vielseitige str.format()-Methode und die moderne f-String-Syntax — jeder mit seinen eigenen Stärken und geeigneten Anwendungsfällen.
Dieses Kapitel behandelt:
- Wann welche Formatierungsmethode verwendet werden sollte und warum
- Den
%-Operator (veraltet, aber in Logs und älteren Codebasen noch verbreitet) str.format()mit positionalen und benannten Platzhaltern- f-Strings (der empfohlene moderne Ansatz)
- Formatspezifizierer: Breite, Ausrichtung, Präzision, Füllzeichen, Vorzeichen und Basis
- Formatierung von Zahlen, Prozentwerten, Datums- und Zeitangaben
- Häufige Fallstricke und Sonderfälle
Einen ausführlichen Blick auf f-Strings — einschließlich Ausdrücken, bedingter Logik und Python-3.12-Verbesserungen — bietet das Kapitel Python f-Strings.
Welche Methode sollte verwendet werden?
| Methode | Python-Version | Wann verwenden |
|---|---|---|
%-Operator | 2.x / 3.x | Veralteter Code, logging-Modul, sehr einfache Ersetzungen |
str.format() | 2.6+ | Wenn wiederverwendbare Formatierungsstrings oder Schlüsselwortargumente benötigt werden |
| f-Strings | 3.6+ | Neuer Code — am schnellsten, am lesbarsten, unterstützt Ausdrücke direkt inline |
Sofern kein Python-2-Code oder eine ältere Python-3-Codebasis gepflegt wird, sollten f-Strings verwendet werden. Sie werden zur Laufzeit ausgewertet, verursachen keinen zusätzlichen Aufruf-Overhead und halten den Variablennamen dort, wo er im String erscheint.
Der %-Operator (veraltete Formatierung)
Der %-Operator ersetzt Werte in einem Formatierungs-String mithilfe von C-artigen Konvertierungsspezifizierern.
Häufige Konvertierungsspezifizierer:
| Spezifizierer | Bedeutung |
|---|---|
%s | String (ruft str() auf dem Wert auf) |
%d | Vorzeichenbehaftete ganze Zahl |
%f | Gleitkommazahl |
%r | repr() des Werts |
%% | Ein literales %-Zeichen |
Breite und Präzision mit %
Feldbreite und Dezimalpräzision lassen sich direkt im Spezifizierer steuern:
pi = 3.14159265
print("%10.3f" % pi) # right-aligned in a 10-char field, 3 decimal places
# 3.142
print("%-10.3f|" % pi) # left-aligned
# 3.142 |
print("%010.3f" % pi) # zero-padded
# 000003.142Fallstrick: Einzelwerte vs. Tupel
Beim Ersetzen eines einzelnen Werts ist die Übergabe als Tupel der sichere Ansatz:
value = "hello"
# Risky — if value were itself a tuple, this would fail:
# print("Got: %s" % value)
# Safe:
print("Got: %s" % (value,))
# Got: hellostr.format() — Flexible Platzhalter-Formatierung
Die str.format()-Methode ersetzte den %-Operator ab Python 2.6+. Sie verwendet {} als Platzhalter und unterstützt positionale, indizierte und Schlüsselwortargumente.
Positionale und indizierte Platzhalter
Benannte (Schlüsselwort-)Platzhalter
Benannte Platzhalter machen Formatierungsstrings selbsterklärend und sind besonders nützlich, wenn derselbe Wert mehrfach vorkommt oder wenn der Formatierungsstring aus einer Konfigurationsdatei stammt.
Formatierungsstrings wiederverwenden
Da str.format() einen String als Eingabe entgegennimmt, kann die Vorlage in einer Variablen gespeichert und wiederverwendet werden:
template = "Hello, {name}! You have {count} new messages."
print(template.format(name="Alice", count=3))
print(template.format(name="Bob", count=0))
# Hello, Alice! You have 3 new messages.
# Hello, Bob! You have 0 new messages.f-Strings — Moderne Python-Formatierung
f-Strings (formatierte String-Literale) stellen dem String f oder F voran und werten jeden Ausdruck innerhalb von {} zur Laufzeit aus. Sie sind ab Python 3.6 verfügbar und der empfohlene Ansatz für neuen Code.
name = "John"
age = 25
print(f"My name is {name} and I am {age} years old.")
# My name is John and I am 25 years old.f-Strings unterstützen jeden gültigen Python-Ausdruck innerhalb der geschweiften Klammern — Arithmetik, Methodenaufrufe, Bedingungen und mehr:
items = ["apple", "banana", "cherry"]
print(f"Cart has {len(items)} items. First: {items[0].upper()}.")
# Cart has 3 items. First: APPLE.
x = -7
print(f"Absolute value: {abs(x)}")
# Absolute value: 7Den vollständigen Leitfaden, einschließlich Debugging mit =, mehrzeiligen f-Strings und Python-3.12-Erweiterungen, bietet das Kapitel Python f-Strings.
Formatspezifizierer: Die Mini-Sprache
Sowohl str.format() als auch f-Strings verwenden dieselbe Formatspezifikations-Mini-Sprache innerhalb von {} nach einem Doppelpunkt:
{[field_name]:[fill][align][sign][#][0][width][grouping][.precision][type]}Die folgende Tabelle zeigt die nützlichsten Optionen:
| Option | Zeichen | Wirkung |
|---|---|---|
| Ausrichtung | < > ^ | Links, rechts, zentriert |
| Füllzeichen | beliebiges Zeichen | Füllt den Auffüllbereich (zusammen mit Ausrichtung und Breite) |
| Vorzeichen | + - | + für positive Zahlen anzeigen; standardmäßig nur Minus; Leerzeichen für positive Zahlen |
| Präfix | # | 0x für Hex, 0o für Oktal, 0b für Binär |
| Nullauffüllung | 0 | Mit Nullen statt Leerzeichen auffüllen |
| Breite | ganze Zahl | Minimale Feldbreite |
| Gruppierung | , oder _ | Tausendertrennzeichen |
| Präzision | .n | Dezimalstellen (Gleitkomma) oder max. Zeichen (Strings) |
| Typ | d f e g x o b % | Ganzzahl, Gleitkomma, wissenschaftlich, allgemein, Hex, Oktal, Binär, Prozent |
Ausrichtung und Breite
text = "hello"
print(f"{text:<10}|") # left-aligned in 10-char field
# hello |
print(f"{text:>10}|") # right-aligned
# hello|
print(f"{text:^10}|") # centered
# hello |
print(f"{text:*^10}|") # centered, filled with *
# **hello***|Dieselben Ausrichtungsspezifizierer funktionieren auch mit str.format(). Hier ein Beispiel, das Ausrichtung und Präzision kombiniert:
Zahlenformatierung
x = 123.456789
print(f"{x:.2f}") # two decimal places
# 123.46
print(f"{x:,.2f}") # thousands separator, two decimal places
# 123.46
print(f"{x:+.2f}") # explicit plus sign for positive numbers
# +123.46
print(f"{x:10.2f}") # right-aligned in a 10-char field
# 123.46
print(f"{x:<10.2f}|") # left-aligned
# 123.46 |
print(f"{x:010.2f}") # zero-padded to 10 characters
# 0000123.46Große Zahlen und Prozentwerte
population = 8_100_000_000
print(f"{population:,}") # comma separator
# 8,100,000,000
print(f"{population:_}") # underscore separator (Python 3.6+)
# 8_100_000_000
ratio = 0.8567
print(f"{ratio:.1%}") # percentage, one decimal place
# 85.7%Ganzzahl-Basen
n = 255
print(f"{n:d}") # decimal (default)
# 255
print(f"{n:x}") # lowercase hexadecimal
# ff
print(f"{n:X}") # uppercase hexadecimal
# FF
print(f"{n:#x}") # hex with 0x prefix
# 0xff
print(f"{n:o}") # octal
# 377
print(f"{n:b}") # binary
# 11111111
print(f"{n:#b}") # binary with 0b prefix
# 0b11111111Dieselben Spezifizierer können auch mit str.format() verwendet werden:
Wissenschaftliche Notation
avogadro = 6.02214076e23
print(f"{avogadro:.3e}") # scientific notation, 3 decimal places
# 6.022e+23
print(f"{avogadro:.3E}") # uppercase E
# 6.022E+23
print(f"{avogadro:.3g}") # general: compact form, removes trailing zeros
# 6.02e+23Strings mit format() und f-Strings formatieren
Alle drei Ansätze erzeugen dieselbe Ausgabe bei einer einfachen Ersetzung:
String-spezifische Spezifizierer ermöglichen die Steuerung von Kürzung und Auffüllung:
s = "Python"
print(f"{s:.3}") # truncate to 3 characters
# Pyt
print(f"{s:10}") # pad to width 10 (left-aligned by default for strings)
# Python
print(f"{s:>10}") # right-aligned
# Python
print(f"{s:*^12}") # centered, filled with *
# ***Python***Datums- und Zeitformatierung
Beim Formatieren von datetime-Objekten mit f-Strings oder str.format() werden strftime-Formatcodes innerhalb der geschweiften Klammern verwendet:
import datetime
date = datetime.datetime(2024, 3, 15, 10, 30, 0)
# Default string representation
print(f"Default: {date}")
# Default: 2024-03-15 10:30:00
# strftime codes inside the format spec
print(f"Formatted: {date:%B %d, %Y}")
# Formatted: March 15, 2024
print(f"Time only: {date:%H:%M:%S}")
# Time only: 10:30:00
print(f"ISO-style: {date:%Y-%m-%d}")
# ISO-style: 2024-03-15Dieselbe Syntax funktioniert auch mit str.format():
import datetime
date = datetime.datetime(2024, 3, 15, 10, 30, 0)
print("The date is {:%B %d, %Y}".format(date))
# The date is March 15, 2024Für erweiterte Datumsformatierung bietet das Kapitel Python Modify Strings weitere Techniken zur String-Bearbeitung.
Fortgeschrittene Techniken
Verschachtelte Ausdrücke in f-Strings
f-Strings erlauben die dynamische Berechnung des Formatspezifizierers:
width = 10
precision = 3
value = 3.14159
print(f"{value:{width}.{precision}f}")
# output: 3.142 (right-aligned in a 10-char field, 3 decimal places)Formatspezifikation mit format() und Variablen
Dieselbe Technik funktioniert mit str.format() über verschachtelte {}:
width = 8
print("{:{width}}".format("left", width=width))
# left Bedingte Formatierung in f-Strings
Da f-Strings jeden Ausdruck auswerten, können bedingte Ausdrücke direkt inline verwendet werden:
score = 73
label = f"{'pass' if score >= 60 else 'fail'}"
print(f"Score {score}: {label}")
# Score 73: passDebugging mit = (Python 3.8+)
Durch Anhängen von = innerhalb eines f-Strings werden sowohl der Ausdruck als auch sein Wert ausgegeben — sehr nützlich zum Debuggen:
x = 42
y = x * 2
print(f"{x=}, {y=}")
# x=42, y=84Häufige Fallstricke
1. Maskierung geschweifter Klammern. Um ein literales { oder } in einem formatierten String einzufügen, muss es verdoppelt werden:
print(f"Use {{curly braces}} in f-strings")
# Use {curly braces} in f-strings2. Anführungszeichen innerhalb von f-Strings. In Python 3.11 und früher darf der Ausdruck innerhalb von {} nicht denselben Anführungszeichentyp wie der äußere f-String verwenden:
names = ["Alice", "Bob"]
# Wrong in Python <= 3.11:
# print(f"First: {names[0].upper()}") -- this is fine
# print(f"{'Alice'.upper()}") -- single quotes inside double-quoted f-string is fine
# But nesting the same quotes fails:
# print(f"{names["Alice"]}") -- SyntaxError in <= 3.11
# Safe approach for <= 3.11:
key = "Alice"
print(f"{key.upper()}")
# ALICE3. Die %-Tupel-Falle. Wenn mit %-Formatierung ein einzelner Wert verwendet wird, der selbst ein Tupel ist, muss er eingehüllt werden:
coords = (10, 20)
# This raises TypeError because % sees a 2-element tuple:
# print("Position: %s" % coords)
# Fix: wrap in a 1-element tuple
print("Position: %s" % (coords,))
# Position: (10, 20)4. str.format() und Sicherheit. Niemals nicht vertrauenswürdige Benutzereingaben als Formatierungsstring an str.format() übergeben — ein bösartiges Template kann auf Objektattribute zugreifen und Daten offenlegen. f-Strings sind immer fest kodierte Strings und daher nicht anfällig für dieses Problem.
Praktischer Vergleich
Hier wird dieselbe Ausgabe mit allen drei Methoden nebeneinander erzeugt:
item = "widget"
qty = 42
unit_price = 4.5
# % operator
print("%-12s %4d $%7.2f" % (item, qty, unit_price))
# str.format()
print("{:<12} {:>4} ${:>7.2f}".format(item, qty, unit_price))
# f-string
print(f"{item:<12} {qty:>4} ${unit_price:>7.2f}")
# All print:
# widget 42 $ 4.50Zusammenfassung
- f-Strings für neuen Python-3.6+-Code verwenden: sie sind am lesbarsten und schnellsten.
str.format()verwenden, wenn ein wiederverwendbarer Vorlagen-String benötigt wird oder Python 2.6+ unterstützt werden muss.%nur in veralteten Codebasen oder beim Arbeiten mit demlogging-Modul verwenden (das die Formatierung aufschiebt, bis der Log-Eintrag tatsächlich ausgegeben wird).- Die Formatspezifikations-Mini-Sprache (
width,precision,align,fill,type) wird fürstr.format()und f-Strings auf dieselbe Weise angewendet.
Verwandte Kapitel:
- Python f-Strings — ausführlicher Blick auf f-String-Ausdrücke und Python-3.12-Features
- Python Strings — String-Grundlagen, Indizierung und Slicing
- Modify Strings — eingebaute String-Methoden
- Escape Characters — Sonderzeichen in Strings