Python-Tutorial: Die Format-Methode am Beispiel von Datumsangaben

Python bietet umfangreiche Möglichkeiten die Ausgabe zu formatieren. Lernen Sie in im Tutorial unseres Trainers René Degen die einfache Ausgabe von Zeichenketten und Datumsangaben mit der format-methode sowie mit f-strings kennen.

Autor René Degen
Datum 18.05.2022
Lesezeit 9 Minuten

Die sorgfältige Ausgabe von Resultaten oder Fehlermeldungen ist die Visitenkarte eines Skripts. Dank der Python String Methode format() stehen hierfür umfangreiche Möglichkeiten zur Verfügung, die auf unterschiedliche Weise in Zeichenketten eingebunden werden können. Mit den f-Strings steht seit Python 3.6 zudem eine kompaktere Art der Verwendung bereit.

Was ist und kann die Methode format?

Für die Formatierung von Zeichenketten bietet Python 3 die format-Methode an. In einer Zeichenkette können Sie Platzhalter definieren, die dann durch bestimmte Werte ersetzt werden.

Die Platzhalter sind durch geschweifte Klammern eingefasst und können entweder durch Zahlen, Zeichenketten oder durch ihre Position angesprochen werden.

Die verschiedenen Formen können auch vermischt werden. Wie das konkret aussieht, zeigen wir hier direkt im interaktiven Modus des Interpreters:

 
>>> # Nummerierung der Platzhalter
>>> "{0} macht {1}".format("Python", "Spass")
'Python macht Spass'

Die Platzhalter werden von 0 an fortlaufend nummeriert und die Parameter der format-Methode eingesetzt. Diese Nummerierung kann auch weggelassen werden. Die Werte werden dann in der Reihenfolge des Auftretens eingesetzt:

 
>>> # Position der Platzhalter
>>> "{} macht {}".format("Die Kuh", "Muh")
'Die Kuh macht Muh'

Schliesslich können auch Namen als Platzhalter verwendet werden, dies bietet den Vorteil der mehrfachen Verwendung. Hier wird die Währung zweimal eingesetzt:

 
>>> # Platzhalter mit Namen, gemischt mit Positionsparametern
>>> "Kosten: {curr} {}, MwSt: {curr} {}".format(
... 100, 7.7, curr = 'CHF')
'Kosten: CHF 100, MwST: CHF 7.7'

Welche Form auch immer verwendet wird, die Verwendung wirkt etwas sperrig. Wäre im obigen Beispiel die Währung ‘CHF’ nicht hardcodiert, sondern in einer Instanz des Namens curr abgelegt, würde die Definition eine unschöne Redundanz beinhalten.

 
>>> curr = 'EUR'
>>> "Kosten: {curr} {}, MwSt: {curr} {}".format(
... 80, 20, curr = curr)
'Kosten: EUR 80, MwST: EUR 20'

Die String format Methode

Mit der Python-Version 3.6 wurde für diesen Fall ein spezielles String-Literal f”” eingeführt. Diese Form erzwingt zwar die Definition der einzelnen Instanzen, ist aber in der Anwendung deutlich kürzer und bei guter Namensgebung auch sehr gut lesbar.

 
>>> curr = 'EUR'
>>> kosten = 80
>>> mwst = kosten * 0.20
>>> # f-String
>>> f"Kosten: {curr} {kosten}, MwSt: {curr} {mwst}"
'Kosten: EUR 80, MwSt: EUR 16.0'

Nun bietet die Formatierung nicht nur die Einbettung von Werten in eine Zeichenkette, sondern auch die verschiedene Formatangaben der einzelnen Werte. In der Online-Dokumentation von Python wird dies als «Format-Definition Mini-Language» bezeichnet.

Die Möglichkeiten dieser Angaben sind mehr als ausreichend für den Alltagsgebrauch und bestehen im Wesentlichen aus der Ausrichtung, der Weite, gegebenenfalls einem Vorzeichen sowie Genauigkeit und einem Typ. Die Formatangabe wird durch einen Doppelpunkt vom Namen des Platzhalters getrennt.

Das zeigen wir am einfachsten an einigen Beispielen, hier unter Verwendung der print-Methode für die platzsparende Anweisung auf einer Zeile und um trotzdem die identische Weite sichtbar zu machen:

 
>>> cur = 'CHF'
>>> cost = 42
>>> vat = cost * 0.077
>>> print(f"Basis{cur:>4}{cost:6.2f}\nMwSt{cur:>4}{vat:6.2f}")
Basis: CHF 42.00
MwSt:  CHF  3.23

Die Währungskennzeichnung wird hier explizit rechtsbündig (angegeben mit dem Zeichen “>”) in der Weite 4 (“4”) Zeichen angeordnet, während die Beträge als Gleitpunktzahl in der Weite 6 Zeichen mit 2 Nachkommastellen – auch gerade gerundet – (“6.2f”) dargestellt werden.

 
>>> l,r  = 'l', 'r'
>>> pos, neg = 20, -30
>>> print(f"Text {l:<4} {r:_>4}\nZahl {pos:0>4d} {neg:>4d}")
Text l   ___r
Zahl 0020  -30

Hier wird ein Text ein Mal links- und ein Mal rechtsbündig ausgerichtet, im letzteren Fall mit einem Füllzeichen “_” ergänzt, wie dies auch für die Zahl mit dem üblicheren Füllzeichen “0” gemacht wird.

Es sei hier auch angemerkt, dass jede Instanz – falls sie nicht durch die Formatangabe gesteuert ist – die entsprechende Klassen-Methode __str__ aufruft, um die Ausgabe bzw. Bildung der Zeichenkette zu bewerkstelligen.

Datumsangaben in Python mit der format-Methode

Eine Besonderheit und leider auch Quelle für Undeutlichkeiten sind Datumsangaben. In unserem Sprachraum schreiben wir das Datum in der Form Tag.Monat.Jahr und seit dem Jahr 2000 sind hoffentlich viele dazu übergegangen, das Jahr nicht mehr auf die letzten zwei Stellen abzukürzen.

Ich möchte auch gerade die Gelegenheit nutzen, die Darstellung des Datums gemäss der ISO-Norm 8601 zu bewerben. Dabei wird das Datum in der Reihenfolge der Grösse der Einheit beschrieben, also Jahr, dann Monat und schliesslich Tag (möglicherweise gefolgt von der Zeit in analoger Weise). Zur besseren Lesbarkeit wird häufig das Trennzeichen “-” verwendet, also beispielsweise “2022-05-01” für den 1. Mai im Jahre 2022.

Diese Form ist eindeutig, da sie keine länderspezifischen Formate enthält und ausserdem natürlich sortierbar.

 
>>> jahr, monat, tag, trenner = 2022, 8, 1, '-'
>>> f"Datum: {jahr:04d}{trenner}{monat:02d}{trenner}{tag:02d}"
'Datum: 2022-08-01'

Dieses Datumfomat bietet sich etwa auch an, um die Namen von Log-Dateien, die periodisch erstellt und rotiert werden sollen, zu bilden. Ein entsprechendes Beispiel befindet sich weiter unten.

Für die Ausgabe von Datums- oder Zeitangaben stehen in der Klasse datetime.date mit der Methode strftime() weitere Formatierungsmethoden zur Verfügung, die sich in der Syntax an den bestehenden Bibliotheken der C-Standard-Bibliothek orientieren. Dabei wird das Ausgabeformat durch das %-Zeichen gesteuert und fast jeder Buchstabe hat seine eigene Bedeutung.

Setzen wir in diesem Kontext das Datum-Objekt ebenfalls auf die kommende Bundesfeier:

 
>>> from datetime import date
>>> d = date.fromisoformat('2022-08-01')
>>> d
datetime.date(2022, 8, 1)
>>> print(d)
2022-08-01
>>> date(2022, 8, 1)
'2022-08-01'
>>> # Was haben wir denn heute?
>>> date.today().isoformat()
'2022-04-12'

Die Vorgabe-String-Representation eines date-Objekts ist also ebenfalls die ISO-Darstellung, wie sie auch durch die explizite Methode isoformat() zur Verfügung steht. Aber wir wollten ja spezielle Formatangaben zeigen:

 
>>> # Formate mit strftime
>>> d.strftime('%Y-%m-%d')
'2022-08-01'
>>> d.strftime('KW %V ist kürzer, Tag %w (%A) ist frei')
'KW 31 ist kürzer, Tag 1 (Monday) ist frei'

Die Buchstaben “Y”, “m” und “d” stehen einigermassen einprägsam für Jahr, Monat und Tag, die Gross-und Kleinschreibung muss aber berücksichtigt werden (die Bedeutung von “M” überlasse ich der Phantasie des Lesenden oder auch dessen Neugierde, dies in der Dokumentation der datetime-Klasse nachzulesen).

Der Buchstabe “V” steht für die Kalenderwoche gemäss ISO-Norm, “w” steht für die Nummer des Wochentags, mit “A” lässt sich auch eine textuelle Repräsentation ausgeben. Wem das bereits zu umfassend ist, soll sich daran erfreuen, dass wir im August 2022 wieder mal ein verlängertes Wochenende haben, weil die Bundesfeier auf einen Montag fällt.

Und nochmals zur Log-Datei:

 
>>> logdatei = "anwendung{}.log".format(date.today())
>>> logdatei
'anwendung2022-04-12.log'

Damit ist garantiert, dass die Logs der Anwendung täglich in eine neue Datei geschrieben werden, sofern der Dateiname unmittelbar vor der Verwendung berechnet wird. Die Handhabung (Rotation) der Logs erfolgt dann ausserhalb der Anwendung gemäss den Firmenvorgaben zu Vertraulichkeit, Nachvollziehbarkeit oder Speicherverfügbarkeit.

Sie möchten lernen mit Python professionell zu programmieren?

Die Zukunft für Python-Entwickler ist rosig. Unerschöpfliche Anwendungsgebiete, Open Source und lebendige Community. Steigen Sie jetzt mit unseren Trainings in die Programmiersprache ein oder vertiefen Sie Ihre Kenntnisse:

Die Zukunft für Python-Entwickler ist rosig. Unerschöpfliche Anwendungsgebiete, Open Source und lebendige Community. Steigen Sie jetzt mit unseren Trainings in die Programmiersprache ein oder vertiefen Sie Ihre Kenntnisse:


Über den Autor

René Degen

Das erste «ls» auf UNIX vor 30 Jahren und immer noch begeistert. René Degen ist dipl. Informatik-Ingenieur ETH, seit 15 Jahren selbstständig unterwegs für Projekte bei Banken und Telecom-Anbietern und nicht zuletzt für Digicomp als Kursleiter im Bereich Unix.