Mit Python lassen sich Dateien sehr direkt anlegen, aber die Wahl des richtigen Zugriffsmodus entscheidet darüber, ob dein Skript sauber arbeitet oder unbeabsichtigt Daten überschreibt. In diesem Artikel zeige ich, wie man Text-, JSON- und Binärdateien erstellt, wann open() genügt und wann pathlib im Alltag die bessere Lösung ist. Dazu kommen typische Fehler, die in Projekten schnell übersehen werden, besonders wenn Verzeichnisse noch nicht existieren oder vorhandene Dateien geschützt werden sollen.
Die wichtigsten Punkte auf einen Blick
-
open(..., "w")legt eine Datei an, überschreibt aber vorhandene Inhalte. -
open(..., "x")ist die sichere Variante, wenn eine Datei nur neu entstehen darf. -
pathlibmacht Pfade lesbarer und ist in vielen Projekten angenehmer als reine String-Pfade. -
Textdateien sollten in der Praxis fast immer mit
encoding="utf-8"geschrieben werden. -
Binärdaten gehören in
wboderwrite_bytes(), niemals in den Textmodus. -
Fehlende Zielordner sind einer der häufigsten Gründe für
FileNotFoundError.

Der direkteste Weg, eine neue Datei anzulegen
Für eine einfache Textdatei reicht oft schon ein einziger Block. Ich nutze dafür gern den Kontextmanager, weil die Datei damit zuverlässig geschlossen wird, selbst wenn unterwegs ein Fehler auftritt:
with open("notizen.txt", "w", encoding="utf-8") as datei:
datei.write("Erste Zeile\n")Der Modus w erzeugt die Datei, falls sie noch nicht existiert, und leert sie ansonsten vollständig. Genau deshalb ist er praktisch, wenn du bewusst etwas neu schreiben willst, aber riskant, wenn vorhandene Daten erhalten bleiben sollen. Für diesen Fall ist x die bessere Wahl: Dann bricht Python mit FileExistsError ab, sobald die Datei bereits existiert. Die Python-Dokumentation empfiehlt für Textdateien außerdem encoding="utf-8", und das halte ich auch in 2026 noch für die vernünftigste Standardentscheidung.
-
wfür neues Schreiben oder bewusstes Überschreiben -
xfür eine Datei, die nur einmal neu angelegt werden darf -
afür Logdateien oder Inhalte, die am Ende ergänzt werden -
r+nur dann, wenn die Datei bereits existiert und gelesen sowie beschrieben werden soll
Wer mehr Struktur will, landet schnell bei pathlib, denn dort wird der Code meist kürzer und besser lesbar.
Warum pathlib in Projekten oft angenehmer ist
pathlib ist für mich die angenehmere Wahl, sobald Pfade nicht nur nebeneinander stehen, sondern zusammengesetzt, geprüft oder weiterverarbeitet werden. Die Python-Dokumentation nennt open(), write_text() und write_bytes() als übliche Wege, Dateien zu erzeugen, und genau das spürt man im Alltag: Mit Path liest sich ein Skript meist sauberer als mit vielen zusammengesetzten Strings.
| Methode | Stärken | Grenzen | Typischer Einsatz |
|---|---|---|---|
open(..., "w") |
Volle Kontrolle über Modus, Encoding und Schreibverhalten | Mehr Boilerplate, überschreibt vorhandene Dateien | Eigene Skripte und klare Schreiblogik |
Path.write_text() |
Sehr kurz, gut lesbar, automatisch geöffnet und geschlossen | Nur für Text, bestehende Datei wird ersetzt | Konfiguration, Protokolle, Markdown, JSON als Text |
Path.touch() |
Erzeugt leere Dateien schnell und sauber | Schreibt keinen Inhalt | Platzhalter, Markerdateien, Tests |
Path.write_bytes() |
Sauber für Rohdaten ohne Textkonvertierung | Erwartet bereits fertige Bytes | Bilder, Archive, PDFs, Binärdaten |
from pathlib import Path
pfad = Path("berichte") / "status.txt"
pfad.parent.mkdir(parents=True, exist_ok=True)
pfad.write_text("Alles bereit\n", encoding="utf-8")Diese Variante ist besonders angenehm, wenn der Dateiname aus mehreren Teilen besteht oder der Zielordner dynamisch entsteht. Ich verwende dann fast immer Path(...) und setze den Elternordner direkt mit an, weil der Code dadurch weniger fehleranfällig wird. Sobald Inhalte mehr als nur Text sind, wird der Dateityp entscheidend.
Text, JSON und Binärdaten sauber trennen
Beim Erstellen einer Datei ist nicht nur der Pfad wichtig, sondern auch die Frage, welche Art von Daten du schreibst. Textdateien gehören in den Textmodus, also typischerweise w oder a, während Binärdaten immer in wb oder ab landen. Sobald du mit Bytes arbeitest, darfst du nicht mehr in Richtung Textdenken; umgekehrt solltest du für normale Texte konsequent bei UTF-8 bleiben.
import json
from pathlib import Path
daten = {"name": "Server-01", "status": "ok"}
Path("daten.json").write_text(
json.dumps(daten, ensure_ascii=False, indent=2),
encoding="utf-8",
)Für JSON ist das wichtig, weil die Datei als Text gespeichert wird. Die Python-Dokumentation weist ausdrücklich darauf hin, dass JSON-Dateien in UTF-8 codiert sein sollen. In der Praxis heißt das: write_text() mit encoding="utf-8" ist hier die richtige Richtung, nicht irgendein Umweg über Binärdaten.
from pathlib import Path
rohdaten = b"\x89PNG\r\n\x1a\n..."
Path("bild.png").write_bytes(rohdaten)Bei Binärdaten ist der Unterschied noch deutlicher: Ein Bild, ein ZIP-Archiv oder ein PDF darf nicht durch Textkonvertierung verfälscht werden. Genau deshalb ist write_bytes() so nützlich, wenn du eine Datei mit Python erzeugen willst, die später bitgenau bleiben muss. Bevor der erste Inhalt geschrieben wird, sollte aber der Zielordner stehen.
Verzeichnisse und leere Dateien richtig vorbereiten
Ein häufiger Stolperstein ist nicht die Datei selbst, sondern ihr Umfeld. Wenn der Zielordner fehlt, scheitert die Erstellung schnell mit FileNotFoundError. Ich löse das meist direkt vor dem Schreiben, indem ich den Elternordner anlege und erst danach die Datei befülle:
from pathlib import Path
ziel = Path("logs") / "2026" / "app.log"
ziel.parent.mkdir(parents=True, exist_ok=True)
ziel.write_text("Start\n", encoding="utf-8")Für leere Platzhalter ist touch() praktisch. Damit legst du eine Datei ohne Inhalt an, und falls sie mit exist_ok=True bereits existiert, wird nur der Zeitstempel aktualisiert. Das ist nützlich für Markerdateien, Testdaten oder einfache Vorbereitungen in Deployments und Automatisierungen.
from pathlib import Path
Path("tmp/leer.txt").touch(exist_ok=True)Wenn du später doch Inhalt brauchst, kannst du dieselbe Datei einfach mit write_text() oder open(..., "w") überschreiben. Genau dort schleichen sich die meisten Bugs ein, weil der Unterschied zwischen „neu anlegen“, „anhängen“ und „überschreiben“ im Alltag gern zu locker behandelt wird.
Typische Fehler beim Erstellen von Dateien
Ich sehe in Projekten immer wieder dieselben Fehlerbilder. Sie sind selten spektakulär, aber sie kosten Zeit, weil die Ursache oft nicht direkt dort liegt, wo der Fehler sichtbar wird. Die folgende Übersicht hilft, die häufigsten Probleme schnell einzuordnen:
| Fehler | Was passiert | Besser so |
|---|---|---|
w statt a
|
Vorhandene Inhalte werden gelöscht | Nur dann überschreiben, wenn das wirklich gewollt ist |
Kein with
|
Datei wird nicht sauber geschlossen oder nicht vollständig geschrieben | Den Kontextmanager konsequent verwenden |
| Binärdaten im Textmodus | Datei wird beschädigt oder unlesbar |
wb oder write_bytes() nutzen |
| Ohne UTF-8 bei Text | Umlaute und Sonderzeichen können systemabhängig schiefgehen | Immer explizit encoding="utf-8" setzen |
| Fehlender Zielordner | FileNotFoundError |
Vorher mkdir(parents=True, exist_ok=True) ausführen |
Der klassische Denkfehler ist aus meiner Sicht nicht der Python-Syntaxfehler, sondern das falsche Sicherheitsgefühl beim Schreiben. Eine Datei ist schnell angelegt, aber genauso schnell auch ungewollt leergeräumt, wenn der Modus nicht bewusst gewählt wurde. Darum lande ich in Projekten meist bei einer klaren Standardregel.
Was ich in Projekten standardmäßig verwende
Wenn ich eine neue Datei in einem echten Projekt anlege, entscheide ich nach einem einfachen Muster: Für lesbaren Text nehme ich pathlib oder open() mit encoding="utf-8", für eine sichere Neuanlage x, für leere Marker touch() und für rohe Daten write_bytes(). Das hält den Code übersichtlich und vermeidet die kleinen Fehler, die erst später teuer werden.
-
open(..., "x", encoding="utf-8")wenn Überschreiben ausgeschlossen sein muss -
open(..., "w", encoding="utf-8")wenn bewusst neu geschrieben werden soll -
Path.write_text(..., encoding="utf-8")wenn Lesbarkeit und Kürze wichtig sind -
Path.mkdir(parents=True, exist_ok=True)wenn der Ordner dynamisch entsteht
So bleibt das Erstellen von Dateien in Python nicht nur kurz, sondern auch robust. Wenn du den Zugriff auf Text, JSON und Binärdaten sauber trennst und den Ordneraufbau von Anfang an mitdenkst, ersparst du dir die meisten Folgefehler bei Automatisierung, Logging und Infrastruktur-Skripten.