fbpx

Wie kann ich in Python mit Dateien arbeiten?

Inhalt
    Add a header to begin generating the table of contents

    In vielen Einsatzgebieten von Python sind die Daten bereits in Dateien gesammelt.
    Ich denke da an Server Logs, Excel Listen oder Exporte jeglicher Art.
    Da wäre es doch geschickt, direkt mit diesen Dateien arbeiten zu können, ohne sie erst selbst anfassen zu müssen.

    In dem Artikel möchte ich dir zeigen, wie du Dateien anlegst, kopierst, liest und schreibst.
    Also alles was du in Python für die Arbeit mit Dateien brauchst.

    Das ist der erste Artikel einer kleinen Serie über Dateien. Wenn du wissen möchtest, wie du Dateien kopieren, umbenennen oder archivieren kannst, lies dir diesen Artikel durch.

    Du weißt nicht, was du mit den Dateien machen sollst? Hier findest du Hilfe.

    FunktionBeschreibung
    path.exists() / Path.exists()Prüfen, ob der angegebene Pfad existiert
    path.isfile() / Path.is_file()Prüfen, ob der angegebene Pfad eine Datei ist
    path.isdir() / Path.is_dir()Prüfen, ob der angegebene Pfad ein Ordner ist
    open()Datei zur Bearbeitung (lesen, schreiben) öffnen
    withKeyword zum automatischen schließen von Verbindungen nach Benutzung
    write()In eine Datei schreiben – nicht zeilenweise
    read()Vollständigen Inhalt aus einer Datei lesen
    readlines()Vollständigen Inhalt als Liste aus einer Datei lesen
    readline()Einzelne Zeile aus einer Datei lesen

    Existiert die Datei?

    Lesen aus Dateien, die nicht vorhanden sind, ist meist nicht ganz so lustig.
    Dasselbe gilt natürlich auch für Schreibvorgänge ins nichts. Irgendwie auch nicht so das wahre.
    Deshalb erstmal prüfen, ob die Datei überhaupt existiert.

    Für Operationen mit dem Betriebssystem stellt Python die Bibliothek os zur Verfügung.
    In os gibt es die Bibliothek path.
    Mit path kannst du verschiedene Operationen mithilfe von Pfaden ausführen.
    Unter anderem ist hier eben auch die Funktion exists enthalten, mit der du prüfen kannst, ob an dem angegebenen Pfad auch wirklich etwas existiert.

    from os import path
    print(path.exists('/content/sample_data/california_housing_test.csv'))

    Im Übrigen ist es path egal, ob dein Pfad auf eine Datei oder ein Verzeichnis zeigt. Es geht ausschließlich darum festzustellen, ob der Pfad überhaupt auf irgendetwas zeigt.

    Anmerkung:
    Die Funktion getcwd() in der Bibliothek os steht für “get current working directory” – als “gib mir den aktuellen Pfad in dem ich mich befinde”.
    Ich nutze die Funktion an der Stelle nur, um schnell an einen Pfad zu kommen und nicht großartig etwas tippen zu müssen.

    from os import path, getcwd
    aktueller_pfad = getcwd()
    print(path.exists(aktueller_pfad))

    Wenn du wissen willst, was für eine Art Pfad es ist – also ist es eine Datei oder ein Verzeichnis – dann kannst du aus path die Funktionen isfile() bzw. isdir() dafür nutzen.
    Sie liefern einfach nur einen Boolean, also wahr oder falsch zurück.

    from os import path, getcwd
    aktueller_pfad = getcwd()
    print('Pfad existiert:', path.exists(aktueller_pfad))
    print('Pfad ist eine Datei:', path.isfile(aktueller_pfad))
    print('Pfad ist ein Verzeichnis:', path.isdir(aktueller_pfad))

    Seit Python 3.4 existiert noch das Modul pathlib.
    Damit liefert Python noch einen objektorientierten Ansatz zum Umgang mit Dateisystempfaden.

    from pathlib import Path
    datei = Path('/content/sample_data/california_housing_test.csv')
    ordner = Path(Path.cwd())
    print('Datei existiert:', datei.exists())
    print('Ordner existiert:', ordner.exists())
    print('Pfad ist eine Datei:', ordner.is_file())
    print('Pfad ist ein Verzeichnis:', ordner.is_dir())

    Wie du siehst, genau dasselbe Ergebnis.
    Es sieht einfach nur etwas strukturierter aus. Eben objektorientiert.

    Dateien öffnen

    So nun kannst du also feststellen, ob eine Datei bereits existiert, oder eben nicht.
    Aber um daraus lesen oder hineinschreiben zu können, musst du die Datei natürlich auch noch öffnen.

    Mithilfe des Build-Ins open() lässt sich genau das bewerkstelligen.
    Einfach den gewünschten Pfad und die zu verwendende Operation angeben.
    Und nicht vergessen mit close() an dem Datei-Objekt wird die Datei wieder zu schließen, wenn du fertig bist!

    Unter Operation versteht man die Angabe, in welcher Art und zu welchem Zweck die Datei geöffnet werden soll:

    OperationBedeutung
    wschreiben (erstellen, falls nicht vorhanden)
    rlesen (Fehler falls nicht vorhanden)
    aanhängen (erstellen, falls nicht vorhanden)
    r+für lesen und schreiben öffnen
    xerzeugen (Fehler, falls Datei vorhanden)
    tText-Modus (Standard)
    bBinär-Modus
    datei = open(<PFAD, <OPERATION>)
    datei = open('/content/sample_data/california_housing_test.csv', 'a+')
    datei.close()

    Dateien erstellen

    Für die Erstellung einer Datei gibt es in Python keinen eigenen Befehl.
    Wenn du dir nochmal die Tabelle mit den möglichen Operationen ansiehst, findest du dort das x.
    Das x kannst du benutzen, wenn du eine Datei einfach nur anlegen und sonst nichts damit machen möchtest.
    Das könnte dann so aussehen:

    open('Beispiel_leer.txt', 'x').close()

    Bevor wir weiter machen noch ein kleiner Einschub…
    Mit open und close kann eine Datei zwar geöffnet und im Anschluss wieder geschlossen werden, allerdings kann es doch passieren, dass man vergisst die Datei wieder zu schließen.

    Bleibt die Datei nun offen, kann es unter Umständen zur Datenkorruption kommen und Daten gehen verloren.
    Außerdem soll ja auch im Fehlerfall die Datei nicht offen bleiben.

    Normalerweise würde also eine Datei geöffnet und alle Operationen in einem try-Block ausgeführt werden.
    Anschließend folgt ein finally-Block, der offene Verbindungen, bzw. in dem Fall die geöffnete Datei, wieder schließt.
    Das wäre dann Exception Handling. Das braucht dich hier aber nicht weiter zu interessieren.

    Da das ein so häufiger Anwendungsfall ist, gibt es in Python dafür ein weiteres Keyword: with.
    Wenn du with benutzt, wird dir eben diese Fehlerbehandlung abgenommen und Python kümmert sich intern darum Fehler abzufangen und Dateien, bzw. Verbindungen nach Benutzung zu schließen.

    with open(<PFAD>, <OPERATION>) as datei:
        datei.write('')

    Statt deinen Variablennamen vor das open zu schreiben, schreibst du ihn jetzt mit einem as dahinter.
    Alles, was du mit der Datei machen willst, wird als Block eingerückt unter das with geschrieben.
    Das war’s. Schon kümmert sich Python darum dir die Arbeit abzunehmen.

    Dateien schreiben

    Alles klar? Dann weiter.
    Du hast jetzt erfolgreich eine Datei geöffnet.
    Der Variablenname, den du nach as vergeben hast, enthält jetzt die Verbindung zu deiner Datei – den sogenannten Datei-Handle.

    Der Datei-Handle hat jetzt wiederum einige Funktionen, die du brauchst, um mit deinen Dateien zu arbeiten.
    Als Erstes möchte ich Inhalt in der Datei haben.
    Dafür öffnest du die Datei mit der Operation w, also write / schreiben.
    An deinem Datei-Handle hast du zusätzlich noch die Funktion write().
    Mit write() kannst du ein Stück Text – also einen String – übergeben und er wird so wie er ist in die Datei geschrieben:

    # ohne 'with'
    datei = open('Beispiel.txt', 'w')
    for i in range(10):
        datei.write('Zeile Nummer {0}'.format(i + 1))
    datei.close()
    # mit 'with'
    with open('Beispiel2.txt', 'w') as datei:
        for i in range(10):
            datei.write('Zeile Nummer {0}'.format(i + 1))

    Achtung:
    write() schreibt nicht zeilenweise!
    Wenn du Zeilenumbrüche willst, musst du die selbst mithilfe von \n setzen.
    \n wird hier auch Systemübergreifend verwendet und von Python intern automatisch in das Betriebssystem spezifische Zeichen für einen Zeilenumbruch umgewandelt.

    Inhalt an bestehende Dateien anfügen

    Wenn du mit der Operation w eine Datei zum Schreiben öffnest, wird eine neue Datei erzeugt. PUNKT.
    Das heißt, wenn bereits eine Datei mit Inhalt vorhanden ist, wird die gelöscht und neu angelegt.
    Dein Inhalt geht also verloren.

    Das ist natürlich nicht immer gewünscht.
    Wenn du an bestehende Dateien weitere Daten zufügen möchtest, dann öffne die Datei einfach mit der Operation aappend / anfügen.

    with open('Beispiel.txt', 'a') as datei:
        for i in range(10):
            datei.write('Hinzufügen Zeile {0}\n'.format(i + 1))

    Dateien lesen

    Durch die Angabe der Operation rread / lesen, kannst du eine Datei für Lesezugriffe öffnen.
    Um den Inhalt der Datei vollständig zu lesen, steht an dem Datei-Handle die Methode read() zur Verfügung.

    with open(<PFAD>, 'r') as datei:
        inhalt = datei.read()
    inhalt = ''
    with open('Beispiel.txt', 'r') as datei:
        inhalt = datei.read()
    print(inhalt)

    Möchtest du gleichzeitig aus einer Datei lesen und auch wieder in die Datei reinschreiben, kannst du die Datei mit der Option r+ öffnen.

    inhalt = ''
    with open('Beispiel.txt', 'r+') as datei:
        # datei.write('test')
        inhalt = datei.read()
    print(inhalt)

    Mit read() wird der gesamte Inhalt in einen großen String eingelesen.
    Du hast also einfach ein Text-Stück ohne Unterscheidung in Zeilen.

    Es ist aber auch möglich die Daten in eine Liste einzulesen. Dabei stellt jede Zeile einen einzelnen Eintrag in der Liste dar. Dafür hast du zwei Möglichkeiten. Du kannst entweder dein Datei-Handle direkt in die BuiltIn Funktion list() geben und bekommst somit eine Liste zurück.
    Oder du rufst an deinem Datei-Handle die Funktion readlines() auf. Damit bekommst du auch direkt eine Liste mit allen Zeilen in die Hand gedrückt.

    inhalt_liste_funktion = []
    inhalt_liste_methode = []
    with open('Beispiel.txt', 'r') as datei:
        inhalt_liste_methode = datei.readlines()
    with open('Beispiel.txt', 'r') as datei:
        inhalt_liste_funktion = list(datei)
    print(inhalt_liste_methode)
    print(inhalt_liste_funktion)

    Wie du siehst, bekommst du in beiden Fällen dieselbe Ausgabe.

    In beiden Fällen wird wie gesagt die ganze Datei auf einmal eingelesen. Das ist hier nicht sonderlich problematisch. Aber überleg mal, du hast zum Beispiel ein altes Server-Log mit mehreren Gigabyte an Daten. Die würden dann vollständig in deinen Arbeitsspeicher geladen.
    Das dauert nicht nur lange, sondern kann auch gerne mal dein System lahmlegen.

    Oft suchst du aber nur nach einer Zeile mit bestimmtem Inhalt. Sicher, du brauchst dafür die gesamte Datei – aber eben nicht auf einen Schlag. Jede Zeile einzeln zu betrachten reicht vollkommen aus.
    Dafür kannst du die Funktion readline() nutzen.

    Mit readline() bekommst du immer nur die nächste Zeile geliefert.
    Python merkt sich intern, welche Zeile du zuletzt bekommen hast und gibt dir die nächste, beim nächsten Aufruf.
    Ist das Ende der Datei erreicht, liefert readline() lediglich einen Leerstring ()

    with open('Beispiel.txt', 'r') as datei:
        print(datei.readline())
        print(datei.readline())
        print(datei.readline())

    Ich habe vorhin ja gesagt, dass du deinen Datei-Handle auch einfach in die BuiltIn Funktion list() übergeben kannst, um deine Inhalte zeilenweise in einer Liste zu bekommen.
    Das heißt im Umkehrschluss, dass der Datei-Handle iterierbar ist.
    Und was iterierbar ist, kann natürlich auch in einer Schleife durchlaufen werden.
    Dabei wird intern auch nur jede Zeile einzeln genutzt und du blockierst nicht deinen gesamten Speicher.

    with open('Beispiel.txt', 'r') as datei:
        for zeile in datei:
            print(zeile, end='') # 'end' ersetzt den Zeilenumbruch durch das angegebene Zeichen

    Anmerkung:
    Im Standard fügt print() einen Zeilenumbruch nach der Ausgabe an.
    Da in der Datei schon Zeilenumbrüche enthalten sind – es sind ja einzelne Zeilen – brauchst du den Zeilenumbruch von print() nicht auch noch zusätzlich.
    Sonst hast du eine Leerzeile nach jeder Zeile.
    Also kannst du print() einen weiteren Parameter übergeben: end=.
    Mit end gibst du an, wie print() eine ausgabe beenden soll.
    Das kann jedes beliebige Zeichen sein!
    In dem Beispiel gibst du einfach einen Leerstring (”) rein. Damit wird dann gar nichts an die Ausgabe angehängt und du hast keine doppelten Zeilenumbrüche.

    Zusammenfassung

    • Pfadoperationen können über das Modul path oder seit Python 3.4 über das Modul pathlib durchgeführt werden.
    • path.exists() bzw. Path.exists() prüfen, ob der angegebene Pfad existiert.
    • path.isfile() und path.isdir() bzw Path.is_file() und Path.is_dir() prüfen auf Dateien / Ordner.
    • mit open() wird eine Datei zur Bearbeitung (lesen, schreiben) geöffnet oder angelegt.
    • write() schreibt – nicht zeilenweise – in Dateien
    • read(), readline(), readlines() bieten verschiedene Möglichkeiten zum Lesen von Dateien

    Kurse

    Code Challenges und YouTube Videos führen nicht immer zum gewünschten Erfolg.
    Manchmal ist es besser, gezielt und strukturiert durch ein Thema zu arbeiten.

    Schau dich einfach mal bei meinen Kursen um.
    Ohne lästiges Blah Blah steigen wir direkt in das Thema ein und behandeln alles, was du brauchst.

    Picture of Ingo Janßen

    Ingo Janßen

    Lerne nicht einfach programmieren. Löse Probleme und automatisiere Aufgaben!

    Das könnte dich auch interessieren

    Nach oben scrollen
    Newsletter Popup Form

    Keine Inhalte mehr verpassen?

    Melde dich direkt für den "Code-Kompass" an und erhalte nützliche Tipps und Informationen direkt in deinen Posteingang.