HOWTO zu Formatierter Ausgabe in Python
(C) 2019-2025 T.Birnthaler/H.Gottschalk <howtos(at)ostc.de>
OSTC Open Source Training and Consulting GmbH
www.ostc.de
Dieses Dokument beschreibt die Formatierung von Strings in Python, die auf 3
verschiedene Arten möglich ist (C-printf-Stil, Python-Stil 1 und Python-Stil
2).
1) Dokumentation
2) Einführung
3) Python Stil 2
3.1) Beispiele zum Python Stil 2
4) Python Stil 1
4.1) Beispiele zum Python Stil 1
4.2) Built-in Funktion "format"
5) C-printf-Stil
5.1) Beispiele zum C-printf-Stil
Hilfreiche Seite mit Formatierung-Beispielen
Kochbuch mit Formatierung-Rezepten
Cheatsheet Python Formatting
format()-Function
printf-style String Formatting
printf-style String Formatting
String Methods
Format Specification Mini-Language
Format String Syntax F"..."
Custom String Formatting
Formatter Class
Formatted String Literals
Template Strings (4. Methode)
In Python gibt es 3 Arten, FORMATIERTE Zeichenketten bestehend aus FESTEN
Textteilen und VARIABLEN Datenteilen zu erzeugen. Alle 3 beruhen auf dem
Prinzip, in eine SCHABLONE/ein TEMPLATE (= FORMAT-String bestehend aus TEXT +
PLATZHALTERN) WERTE im passenden Format einzubauen und das Ergebnis als STRING
zurückzugeben:
+------+-----------------+---------------------+--------+-------------------+
| Stil | Bezeichnung | Syntax | Platzh.| Eigenschaften |
+------+-----------------+---------------------+--------+-------------------+
| Py2 | Format-String | F"FMT+WERTE" | {...} | MOD HOCH KOMP NAM |
| Py1 | Format-Funktion | "FMT".format(WERTE) | {...} | MOD MITT LANG P+N |
| C | Analog C-printf | "FMT" % (WERTE) | %... | ALT NIED LANG POS |
+------+-----------------+---------------------+--------+-------------------+
(MOD=modern, HOCH/MITT/NIED=Flexibilität, KOMP=kompakt, NAM=Name,
P+N=Position+Name, POS=Position, FMT=Format)
Hier ein Beispiel für alle 3 Stile mit dem gleichen Ergebnis: Folgende 3 Werte
z = 5678 # Ganzzahl
k = 3.1462 # Fließkommazahl
t = "hallo" # String
werden per Platzhalter mit passendem Formattyp (d=decimal, f=float, s=string)
in einen String eingebaut:
print(F"Zahl {z:6d}, Wert {k:6.2f}, Text {t:10s}") # Py2
print( "Zahl {0:6d}, Wert {1:6.2f}, Text {2:10s}".format(z, k, t)) # Py1
print( "Zahl {a:6d}, Wert {b:6.2f}, Text {c:10s}".format(a=z, b=k, c=t)) # Py1
print( "Zahl %6d, Wert %6.2f, Text %-10s" % (z, k, t)) # C
Es ergibt sich jeweils der gleiche Ergebnisstring (Zahlen rechtsbündig, String
linksbündig):
"Zahl 5678, Wert 3.15, Text hallo "
------ ------ ----------
6d 6.2f -10s/10s
Die PLATZHALTER werden also per {} oder % dargestellt, der TYP-BUCHSTABE am
Ende eines Platzhalters legt den DATENTYP des einzufüllenden Werts fest (Python
prüft dies auch). Der WERT zu einem Platzhalter wird festgelegt durch:
1) Variablenname im Platzhalter {} (Umordnung + Mehrfachverw. möglich)
2a) Position im .format()-Aufruf (Umordnung + Mehrfachverw. möglich)
2b) Name im .format()-Aufruf (Umordnung + Mehrfachverw. möglich)
3) Position im Tupel nach %-Zeichen (KEINE Umordnung + Mehrfachverwendung)
Folgende TYP-BUCHSTABEN sind verfügbar (allen 3 Stilen gemeinsam, * = üblich):
+-----+-------------+--------------------------------------------------------+
| Typ | Name | Bedeutung |
+-----+-------------+--------------------------------------------------------+
| s | string *| Zeichenkette (DEFAULT, weglassbar) | *
| (r) | repr | Repräsentation (NUR im C-Stil, sonst Konvertierung r!) |
| c | character | Zeichen per Code-Nummer (Unicode) |
+-----+-------------+--------------------------------------------------------+
| d | decimal *| Ganzzahl im Dezimalformat | *
| (i) | integer | Ganzzahl im Dezimalformat (NUR im C-Stil, analog "d") |
| n | number | Ganzzahl analog "d" (aber Trennzeichen gemäß locale) |
+-----+-------------+--------------------------------------------------------+
| (b) | binary | Ganzzahl im Binärformat (Ziffern 0/1, NICHT im C-Stil) |
| o | octal | Ganzzahl im Oktalformat (Ziffern 0-7) |
| x X | hexadecimal | Ganzzahl im Hexadezimalformat (x=abcdef, X=ABCDEF) |
+-----+-------------+--------------------------------------------------------+
| f F | float *| Fließkommaz. im Festpunktformat (inf/nan <-> INF/NAN) | *
| e E | exponent | Fließkommaz. im Exponentialformat mit e/E-Zeichen |
| g G | general | "f/F" oder "e/E" je nachdem wo mehr Ziffern darstellbar|
| n | number | Fließkommaz. analog "g" (Trennzeichen gemäß locale) |
+-----+-------------+--------------------------------------------------------+
| (%) | percent | Fließkommazahl analog "f" * 100 + %-Zeichen danach |
| | | (NICHT im C-Stil) |
+-----+-------------+--------------------------------------------------------+
Die Typinformation kann um weitere Angaben ergänzt werden, welche die genaue
FORM der Ausgabe kontrollieren:
* Minimale+maximale Breite (auffüllen/runden/abschneiden)
* Füllzeichen (Standard: Leerzeichen)
* Ausrichtung (Standard: Zahlen rechtsbündig, Strings linksbündig)
* Anzahl Nachkommastellen (Standard: 6)
* Tausender-Komma (Standard: keines)
* Konvertierung (Standard: keine)
* Weitere Eigenschaften
Weitere Besonderheiten sind:
* Ist ein Wert BREITER als in der zugehörigen Format-Angabe festgelegt, dann
"SPRENGT" er die vorgegebene Breite, d.h. Zahlen und Strings werden nicht
abgeschnitten (außer Strings am rechten Rand bei Angabe der Maximal-Breite).
z = 123456789 # Ganzzahl
k = 98765.432 # Fließkommazahl
t = "hallowelt" # String
mit Formatierung::
print(F"Zahl {z:6d}, Wert {k:6.2f}, Text {t:5}") # Py2
print( "Zahl {0:6d}, Wert {1:6.2f}, Text {2:5}".format(z, k, t)) # Py1
print( "Zahl {a:6d}, Wert {b:6.2f}, Text {c:5}".format(a=z, b=k, c=t)) # Py1
print( "Zahl %6d, Wert %6.2f, Text %-5" % (z, k, t)) # C
ergibt:
"Zahl 123456789, Wert 98765.43, Text hallowelt"
------XXX ------XX -----XXXX # XXX = gesprengt
6d 6.2f -5s/5s
* Sollen die Platzhalter-Zeichen "{" und "}" bzw. "%" selbst im Text stehen,
dann sind sie jeweils zu VERDOPPELN:
F"{{ {text} }}" # --> "{ hallo }"
"%d%% (Prozent)" % 19 # --> "19% (Prozent)"
* Text-Literale sind per '...' in "..." einschachtelbar (und umgekehrt):
F"{'TE'+'XT':^10s}" # --> " TEXT "
F'{"TE"+"XT":^10s}' # --> " TEXT "
* Der Platzhalter "{VAR}" (Stil 2) oder "{}" (Stil 1) fügt Variablenwert
TYP-UNABHÄNGIG in passender Breite in den Text ein:
F"Z: {zahl}, W: {wert}, T: {text}" # --> "Z: 5678, W: 3.15, T: hallo"
* Der Platzhalter "{VAR=}" gibt Variablen-NAME + -WERT mit "=" dazwischen aus
(zu Debug-Zwecken nützlich):
F"{zahl=} {wert=} {text=}" # --> "zahl=5678 wert=3.15 text=hallo"
Die Formatangabe (Format String Syntax) hat folgende Form (ohne Zwischenraum,
EXPR ist ein beliebiger Ausdruck, dessen Wert eingefüllt wird, !CONV und :SPEC
sind optional):
"{" EXPR ":"}"
"{" EXPR ":" SPEC "}"
"{" EXPR "!" CONV ":" SPEC "}"
Bedeutung:
+------+----------------------------------------------------------+
| EXPR | Zu formatiertendes Objekt (Variablenname/Rechenausdruck) |
| CONV | Festlegung der Konvertierung gemäß folgender Tabelle |
| SPEC | Festlegung der Formatierung gemäß folgender Tabelle |
+------+----------------------------------------------------------+
CONV konvertiert den Wert gemäß folgender Regeln:
+----+---------+--------------------------------------------+
| !a | ascii | Funktion ascii() auf Wert anwenden |
| !r | repr | Funktion repr() auf Wert anwenden |
| !s | string | Funktion str() auf Wert anwenden (Default) |
+----+---------+--------------------------------------------+
Die Format Specification Mini-Language SPEC legt die Formatierung des Wertes
über folgende Komponenten fest (diese Reihenfolge, kein Zwischenraum, alle
Elemente sind optional außer FILL erfordert gleichzeitig ALIGN):
[[FILL] ALIGN] [SIGN] [#] [0] [WIDTH] [GRPOPT] [.PREC] [TYPE]
Bedeutung:
+--------+------------------------------------------------------------------+
| FILL | Füllzeichen (Standard Leerzeichen " ", "}" nicht erlaubt |
| ALIGN | "<" (left), ">" (right), "^" (center), "=" (zw. Vorz. und Zahl) |
| SIGN | "+" ("+"/"-" erzwingen), "-" ("-" falls nötig), " " (" "/"-") |
| # | Setzt "0b", "0o" oder "0x" vor Ganzzahlen (abhängig von TYPE) |
| 0 | Zahlen mit "0" auffüllen (FILL ist allgemeiner) |
| WIDTH | Minimale Breite (mit " ", "0" oder FILL aufgefüllt) |
| GRPOPT | "_" oder "," erzeugt Tausendertrenner-Zeichen (3er-Gruppen) |
| .PREC | Maximale Breite bei Strings / Anzahl Nachkommastellen bei Zahlen |
| TYPE | "bcdeEfFgGnosxX%" analog obiger Typtabelle ("i" nur im C-Stil) |
+--------+------------------------------------------------------------------+
Beispiel:
F"Zahl {z:6d}, Wert {k:6.2f}, Text {t:10s}") # Variable
F"Zahl {z*5+2:6d}, Wert {k/5.0:6.2f}, Text {t+'X':10s}") # Rechenausdruck
Ergibt:
"Zahl 5678, Wert 3.14, Text hallo "
"Zahl 28392, Wert 0.63, Text halloX "
------ ------ ----------
6d 6.2f 10s
ACHTUNG: Im Python Stil 2 lassen sich mit weiteren (eingeschachtelten) Klammern
{...} beliebige Teile der Format-Angabe per Variable Rechenausdruck füllen
(Makro-Logik):
breite = 10
nkst = 3
typ = "d"
ausr = "<"
F"Zahl {z:{ausr}{breite}{typ}}, Wert {k:{breite}.{nkst}f}, Text {t:{breite}s}"
Ergibt:
"Zahl 5678 , Wert 3.142, Text hallo "
---------- ---------- ----------
10d 10.3f 10s
zahl = 1234567.89 # |123456789012| (Ausgabespalten)
#
F"{zahl:+12.1f}" # --> ' +1234567.9'
F"{zahl:+012.1f}" # --> '+001234567.9'
F"{zahl:<+12.1f}" # --> '+1234567.9 '
F"{zahl:<-12.1f}" # --> '1234567.9 '
F"{zahl:< 12.1f}" # --> ' 1234567.9 '
F"{zahl:<12.1f}" # --> '1234567.9 '
F"{zahl:<012.1f}" # --> '1234567.9000'
F"{zahl:012.1f}" # --> '0001234567.9'
F"{zahl:f}" # --> '1234567.890000' # Std: 6 Nachkommastellen
#
F"{zahl:*=+12.1f}" # --> '+**1234567.9'
F"{zahl:*>+12.1f}" # --> '** 1234567.9'
F"{zahl:-012.1f}" # --> '0001234567.9'
F"{zahl:,.2f}" # --> '1,234,567.89'
F"{zahl:_.2f}" # --> '1_234_567.89'
F"{zahl:12,.2f}" # --> '1,234,567.89'
F"{zahl:12_.2f}" # --> '1_234_567.89'
#
text = "hallowelt" # |123456789012| (Ausgabespalten)
#
F"{text:s}" # --> 'hallowelt'
F"{text:12s}" # --> 'hallowelt '
F"{text:<12s}" # --> 'hallowelt '
F"{text:^12s}" # --> ' hallowelt '
F"{text:>12s}" # --> ' hallowelt'
F"{text:012s}" # --> 'hallowelt000'
F"{text:12.12s}" # --> 'hallowelt '
F"{text:6.6s}" # --> 'hallow'
F"{text:12.6s}" # --> 'hallow '
Die Formatangabe (Format String Syntax) hat folgende Form (ohne Zwischenraum,
INDEX ist eine Positionsnummer (startet mit 0) oder ein Name, dessen Wert
eingefüllt wird, !CONV und :SPEC sind optional):
"{}"
"{" INDEX/NAME "}"
"{" INDEX/NAME ":" SPEC "}"
"{" INDEX/NAME "!" CONV ":" SPEC "}"
Bedeutung:
+-------+----------------------------------------------------------+
| INDEX | Position in Werte-Liste des .format(WERTE)-Aufrufs |
| NAME | Name des Wertes in .format(NAME=WERT, ...)-Aufruf |
| CONV | Festlegung der Konvertierung gemäß Tabelle weiter unten |
| SPEC | Festlegung der Formatierung gemäß Tabelle weiter unten |
+-------+----------------------------------------------------------+
Im Python-Stil 1 steht im Platzhalter vor einem ":" ein INDEX (startet mit 0),
welche die POSITION in der Werte-Liste im .format(WERTE)-Aufruf angibt
(Reihenfolge der Nummern beliebig, gleiche Nummer mehrfach erlaubt). Ohne Index
werden die Werte von links nach rechts in die Platzhalter eingefüllt (":" ist
trotzdem notwendig!). Alternativ sind auch NAMEN für die format()-Parameter
vergebbar, die vor dem ":" als Referenz verwendbar sind:
"Zahl {:6d}, Wert {:6.2f}, Text {:10s}".format(z, k, t) # Index automatisch
"Zahl {0:6d}, Wert {1:6.2f}, Text {2:10s}".format(z, k, t) # Index explizit
"Zahl {a:6d}, Wert {b:6.2f}, Text {c:10s}".format(a=z, b=k, c=t) # Name
Ergibt:
"Zahl 5678, Wert 3.14, Text hallo "
"Zahl 5678, Wert 3.14, Text hallo "
"Zahl 5678, Wert 3.14, Text hallo "
------ ------ ----------
6d 6.2f 10s
Im einfachsten Fall genügt "{}" als Platzhalter, diese werden von links nach
rechts mit den Werten in .format(...) in der NOTWENDIGEN Breite gefüllt (eine
Typprüfung findet hier nicht statt):
"Zahl {}, Wert {}, Text {}".format(z, k, t)
Ergibt:
"Zahl 5678, Wert 3.1415, Text hallo"
---- ------ -----
zahl = 1234567.89 # |123456789012| (Ausgabespalten)
#
"{:+12.1f}".format(zahl) # --> ' +1234567.9'
"{:+012.1f}".format(zahl) # --> '+001234567.9'
"{:<+12.1f}".format(zahl) # --> '+1234567.9 '
"{:<-12.1f}".format(zahl) # --> '1234567.9 '
"{:< 12.1f}".format(zahl) # --> ' 1234567.9 '
"{:<12.1f}".format(zahl) # --> '1234567.9 '
"{:<012.1f}".format(zahl) # --> '1234567.9000'
"{:012.1f}".format(zahl) # --> '0001234567.9'
"{:f}".format(zahl) # --> '1234567.890000' # Std: 6 Nachkommastellen
#
"{:*=+12.1f}".format(zahl) # --> '+**1234567.9'
"{:*> 12.1f}".format(zahl) # --> '** 1234567.9'
"{:-012.1f}".format(zahl) # --> '0001234567.9'
"{:,.2f}".format(zahl) # --> '1,234,567.89'
"{:_.2f}".format(zahl) # --> '1_234_567.89'
"{:12,.2f}".format(zahl) # --> '1,234,567.89'
"{:12_.2f}".format(zahl) # --> '1_234_567.89'
text = "hallowelt" # |123456789012| (Ausgabespalten)
#
"{:s}".format(text) # --> 'hallowelt'
"{:12s}".format(text) # --> 'hallowelt '
"{:<12s}".format(text) # --> 'hallowelt '
"{:^12s}".format(text) # --> ' hallowelt '
"{:>12s}".format(text) # --> ' hallowelt'
"{:012s}".format(text) # --> 'hallowelt000'
"{:12.12s}".format(text) # --> 'hallowelt '
"{:6.6s}".format(text) # --> 'hallow'
"{:12.6s}".format(text) # --> 'hallow '
HINWEIS: Ein EINZELNER Wert kann durch die Built-in Funktion "format()" gemäß
obiger Syntax formatiert werden (geschweifte Klammern "{}" sind wegzulassen):
format(z, "6d") # --> " 5678"
format(k, "6.2f") # --> " 3.14"
format(t, "10s") # --> "hallo "
Die Built-in Funktion "format(VALUE, FMTSPEC)" ruft folgende Funktion auf:
type(VALUE).__format__(VALUE, FMTSPEC)
Formatelemente beginnen mit dem Zeichen "%" und enden mit einem Typbuchstaben
TYPE (ohne Zwischenraum, das %-Zeichen und TYPE müssen angegeben werden, die
restlichen Elemente dürfen fehlen).
% [(MAP)] [FLAGS] [WIDTH] [.PREC] [LENMOD] TYPE
Bedeutung:
+--------+------------------------------------------------------------------+
| (MAP) | Dictionary Key (zugehöriger Wert muss ein Dictionary sein, |
| | (KEY) in Klammern greift auf zugehörigen VALUE in Dictionary zu) |
| FLAGS | "#" Alternative Form ("0o", "0x", "0X") |
| | "0" Mit "0" statt Leerzeichen auffüllen |
| | "-" Linksbündig (statt rechtsbündig) |
| | " " Vorzeichen "+" als Leerzeichen ausgeben |
| | "+" Vorzeichen "+" als "+" ausgeben |
| WIDTH | Minimale Breite (mit " " oder "0" aufgefüllt) |
| .PREC | Maximale Breite bei Strings / Anzahl Nachkommastellen bei Zahlen |
| LENMOD | "hlL" (short/long/long long, in Python irrelevant) |
| TYPE | "bcdeEfFgiGnosxX%" analog obiger Typtabelle ("i" nur im C-Stil) |
+--------+------------------------------------------------------------------+
zahl = 1234567.89 # |123456789012| (Ausgabespalten)
#
"%+12.1f" % zahl # --> ' +1234567.9'
"%+012.1f" % zahl # --> '+001234567.9'
"%-+12.1f" % zahl # --> '+1234567.9 '
"%--12.1f" % zahl # --> '1234567.9 '
"%- 12.1f" % zahl # --> ' 1234567.9 '
"%-12.1f" % zahl # --> '1234567.9 '
"%-012.1f" % zahl # --> '1234567.9 '
"%012.1f" % zahl # --> '0001234567.9'
"%f" % zahl # --> '1234567.890000' # Std: 6 Nachkommastellen
#
text = "hallowelt" # |123456789012| (Ausgabespalten)
#
"%s" % text # --> 'hallowelt'
"%12s" % text # --> ' hallowelt'
"%-12s" % text # --> 'hallowelt '
"%012s" % text # --> ' hallowelt'
"%12.12s" % text # --> ' hallowelt'
"%6.6s" % text # --> 'hallow'
HINWEIS: Die %(...)-Syntax erlaubt auch im C-Stil BENANNTE Parameter:
alter = { # Dictionary
"tom" : 18, #
"hans" : 35, #
"rick" : 92 #
} #
#
"%(hans)4d, %(rick)03d %(tom)d, " % alter # --> ' 35, 092, 18'
"%(hans)4d, %(rick)03d %(tom)d, " % { # --> ' 35, 092, 18'
"thon" : 18, "hans" : 35, "rick" : 92 } #