Dateien lesen und schreiben
Dateien
Man findet wohl kaum jemanden im 21. Jahrhundert, der nicht wüsste, was eine Datei ist. Auch wenn nicht
jeder eine exakte Definition geben könnte, also beispielsweise: Eine Datei ist eine Menge von logisch
zusammenhängenden und meist sequentiell geordneten Daten, die auf einem Speichermedium dauerhaft gespeichert
werden und mittels eines Bezeichners bzw. Namens wieder identifizierbar und damit ansprechbar sind.
Die Daten einer Datei existieren also über die Laufzeit eines Programms hinaus. Deswegen werden sie auch
als nicht flüchtig oder persistent bezeichnet.
Auch wenn es so scheinen mag: Das Wort Datei ist kein altes deutsches Wort. Es ist eine künstliche Schöpfung des Deutschen Institutes für Normung (DIN). Die beiden Wörter Daten und Kartei wurden zu dem neuen Wort Datei verschmolzen. Ein solches Kunstwort wird übrigens als Portmanteau oder Kofferwort bezeichnet.
Der Inhalt jeder Datei besteht grundsätzlich aus einer eindimensionalen Aneinanderreihung von Bits, die normalerweise in Byte-Blöcken zusammengefasst interpretiert werden. Die Bytes erhalten erst durch Anwendungsprogramme und das Betriebssystem eine Bedeutung. Sie entscheiden also, ob es sich um eine Textdatei, ein ausführbares Programm oder beispielsweise ein Musikstück oder ein Bild handelt.
Text aus einer Datei lesen
Unser erstes Beispiel zeigt, wie man Daten aus einer Datei ausliest. Um dies tun zu können, muss man zuerst die Datei zum Lesen öffnen. Dazu benötigt man die open()-Funktion. Mit der open-Funktion erzeugt man ein Dateiobjekt und liefert eine Referenz auf dieses Objekt als Ergebniswert zurück. Die open-Funktion erwartet zwei Parameter: Einen Dateinamen, gegebenenfalls mit einem Pfad, und optional kann man den Modus angeben:
open(filename,mode)Im folgenden Beispiel öffnen wir die Datei "yellow_snow.txt" zum Lesen, da der Modus auf "r" (read) gesetzt ist:
fobj = open("yellow_snow.txt", "r")
Alternativ hätte man die obige Anweisung auch ohne die Angabe des "r" schreiben können. Fehlt der
Modus, wird automatisch lesen zum Defaultwert:
fobj = open("yellow_snow.txt")
Nach der Bearbeitung einer Datei, muss diese wieder schlossen werden. Dies
geschieht mit der Methode close:
fobj.close()Das folgende Programmstück liest eine Datei zeielnweise ein und druckt jede Zeile aus, wobei mit der Methode rstrip() etwaige Leerzeichen und Newlines vom rechten Rand entfernt werden:
fobj = open("yellow_snow.txt")
for line in fobj:
print(line.rstrip())
fobj.close()
Die Methode rstrip() im obigen Beisiel dient dazu Leerzeichen (Whitespaces) am rechten Ende des
Strings zu entfernen.
Schreiben in eine Datei
Schreiben geht nahezu analog. Zum Öffnen benutzt man "w" statt "r" als Modus. Daten
schreibt man in eine Datei mit der Methode write des Dateiobjektes.
Beispiel:
fobj_in = open("yellow_snow.txt")
fobj_out = open("yellow_snow2.txt","w")
i = 1
for line in fobj_in:
print(line.rstrip())
fobj_out.write(str(i) + ": " + line)
i = i + 1
fobj_in.close()
fobj_out.close()
In einem Rutsch lesen
Bis jetzt haben wir Dateien Zeile für Zeile mit Schleifen verarbeitet. Aber es kommt öters vor, dass man eine Datei gerne in eine komplette Datenstruktur einlesen will, z.B. einen String oder eine Liste. Auf diese Art kann die Datei schnell wieder geschlossen werde und man arbeitet anschließend nur noch auf der Datenstruktur weiter:
>>> poem = open("ad_lesbiam.txt").readlines()
>>> print(poem)
['V. ad Lesbiam \n', '\n', 'VIVAMUS mea Lesbia, atque amemus,\n', 'rumoresque senum severiorum\n', 'omnes unius aestimemus assis!\n', 'soles occidere et redire possunt:\n', 'nobis cum semel occidit breuis lux,\n', 'nox est perpetua una dormienda.\n', 'da mi basia mille, deinde centum,\n', 'dein mille altera, dein secunda centum,\n', 'deinde usque altera mille, deinde centum.\n', 'dein, cum milia multa fecerimus,\n', 'conturbabimus illa, ne sciamus,\n', 'aut ne quis malus inuidere possit,\n', 'cum tantum sciat esse basiorum.\n', '(GAIUS VALERIUS CATULLUS)']
>>> print(poem[2])
VIVAMUS mea Lesbia, atque amemus,
Im obigen Beispiel wurde das ganze Gedicht in eine Liste namens poem geladen. Wir können nun biespielsweise
die dritte Zeile mit poem[2] ansprechen.
Eine andere angenehme Methode eine Datei einzulesen bietet die Methode read() von open. Mit dieser Methode kann man eine ganze Datei in einen String einlesen, wie wir im folgenden Beispiel zeigen:
>>> poem = open("ad_lesbiam.txt").read()
>>> print(poem[16:34])
VIVAMUS mea Lesbia
>>> type(poem)
>>>
In die Klemme geraten
Beim Programmieren kommt es natürlich immer wieder mal vor, dass man in die Klemme gerät,
aber bei Python ist das wahrscheinlich - hoffen wir - seltener als in anderen Sprachen
der Fall. In die Klemme geraten heißt im Englischen "to get oneself into a pickle".
Aber "to pickle" bedeutet eigentlich einlegen oder pökeln, z.B. saure Gurken.
Aber was hat nun das Pökeln von sauren Gurken mit Python zu tun? Naja ganz einfach:
Python hat ein Modul, was "pickle" heißt und mit dem kann man Python-Objekte
gewissermaßen einlegen, um sie später, also in anderen Sitzungen oder anderen Programmläufen
wieder zu benutzen. Aber jetzt wollen wir wieder seriös werden:
Mit dem Modul pickle (dt. einlegen) lassen sich Objekte serialisiert abspeichern und
zwar so, dass sie später wieder deserialisiert werden können. Dazu dient die Methode
dump, die in ihrer allgemeinen Syntax wie folgt aussieht:
pickle.dump(obj, file[,protocol, *, fix_imports=True])dump() schreibt eine gepickelte Darstellung des Objectes obj in das Dateiobjekt file. Das optionale Argument für das Protokollargument steuert die Art der Ausgabe:
- Protokollversion 0 ist die originale Ablageart von Python, d.h. vor Python3. Dabei handelt es sich um ein für Menchen lesbares Format. Dieser Modus ist abwärts kompatibel mit früheren Pythonversionen.
- Protokollversion 1 benutzt das alte Binärformat. Dieser Modus ist ebenfalls abwärts kompatibel mit früheren Pythonversionen.
- Protokollversion 2 wurde mit 2.3. eingeführt. Es stellt ein effizienteres "Pickling" zur Verfügung.
- Protokollversion 3 wurde mit Python 3.0 eingeführt. Dieser Modus bietet einen hervorragenden Modus Bytes. Dateien, die in diesem Modus erzeugt werden, können nicht mehr in Python 2.x mit dem zugehörigen Pickle-Modul bearbeitet werden. Es handelt sich hierbei um den von Python 3.x empfohlenen Modus. Er stellt auch den Defaultwert dar.
Objekte, die mit pickle.dump() in eine Datei geschrieben worden sind, können mit der Pickle-Methode pickle.load(file) wieder eingelesen werden. pickle.load erkennt automatisch in welchem Format eine Datei erstellt worden ist.
Ein einfaches Beispiel:
>>> import pickle
>>> cities = ["Bern", "Basel","St. Gallen", "Zürich"]
>>> fh = open("data.pkl","bw")
>>> pickle.dump(cities,fh)
>>> fh.close()
Die Datei data.pkl kann wieder in Python eingelesen werden. Dies kann in der gleichen Session
oder dem gleichen Programm geschen, aber meistens werden die Daten natürlich in einem erneuten
Programmlauf oder in einem anderen Programm eingelen. Wir zeigen die Funktionsweise des Einlesens
im folgenden Beispiel:
>>> import pickle
>>> f = open("data.pkl","rb")
>>> staedte = pickle.load(f)
>>> print(staedte)
['Bern', 'Basel', 'St. Gallen', 'Zürich']
>>>
Da nur die Objekte selbst und nicht ihre Namen gespeichert worden sind, müssen wir das Ergebnis
von pickle.load() wieder einer Variablen, - wie in obigem Beispiel gezeit, - zuweisen.

