HOWTO · Python

Projektstruktur für eine Python-Anwendung

Erfahren Sie, wie Sie eine Python-Anwendung strukturieren

Auf dieser Seite

Ein wartbares Python-Projekt hält sein Stammverzeichnis übersichtlich, fasst zusammengehörigen Code in Paketen zusammen und ergänzt unterstützende Verzeichnisse nur, wenn die Anwendung sie benötigt. Wähle die Struktur passend dazu, wie das Programm ausgeführt wird: Eine modular aufgebaute Anwendung kann trotzdem als kleiner Monolith bereitgestellt werden.

Wähle eine passende Struktur für deine Anwendung

Eine übersichtliche Projektstruktur erleichtert es, Code zu finden, zu warten und mit anderen zu teilen. Dafür muss ein Programm nicht in Microservices aufgeteilt werden. Eine kleine Anwendung kann ein einzelnes bereitstellbares Programm bleiben, während ihr zusammengehöriger Code in Module und Pakete gegliedert ist. Lege Verzeichnisse an, wenn sie dem Projekt eine sinnvolle Struktur geben; erstelle keine leeren Ordner, nur um den Aufbau eines größeren Projekts nachzuahmen.

Welche Struktur passt, hängt davon ab, wie die Anwendung ausgeführt wird und was sie enthält. Für ein Befehlszeilenprogramm reichen möglicherweise der Anwendungscode, Angaben zu Abhängigkeiten und Tests. Eine Webanwendung benötigt eventuell zusätzlich Vorlagen und statische Ressourcen. Ein Projekt mit SQLite kann eine lokale Datenbankdatei anlegen; bei einer Verbindung zu einem Datenbankdienst liegen diese Daten üblicherweise außerhalb des Quellverzeichnisses.

Beginne mit dem Projektstammverzeichnis

Das Projektstammverzeichnis enthält die Dateien, die zum Entwickeln, Testen, Dokumentieren und Paketieren der Anwendung dienen. Übliche Beispiele sind eine README.md mit Anleitungen zur Einrichtung und Verwendung, eine LICENSE mit den Bedingungen für Nutzung und Weitergabe des Codes sowie eine Abhängigkeitsdeklaration wie pyproject.toml oder requirements.txt. Diese Dateien haben unterschiedliche Aufgaben; ein Projekt braucht nicht jedes Paketierungs- oder Abhängigkeitsformat.

Für Python-Anwendungen gibt es keinen allgemein vorgeschriebenen Dateinamen für den Einstiegspunkt. Ein Befehlszeilenprogramm lässt sich beispielsweise mit python -m package_name starten; ein Framework oder die Paketierungskonfiguration kann einen anderen Befehl festlegen. Verwende die zum Projekt passende Startmethode, statt anzunehmen, jedes Projekt benötige run.py oder setup.py.

Richte lokal eine virtuelle Umgebung ein, damit die installierten Pakete des Projekts isoliert bleiben. Nimm sie nicht in die Versionsverwaltung auf; Mitwirkende können sie anhand der Abhängigkeitsangaben selbst erstellen. Eine .gitignore-Datei schließt diese Umgebung häufig ebenso aus wie Caches und andere erzeugte Dateien. Das Stammverzeichnis kann übersichtlich bleiben: Ergänze Dokumentation oder Paketierungskonfiguration nach Bedarf.

Gliedere den Anwendungscode in Pakete

Fasse Python-Module nach ihren Aufgaben zusammen. Ein Blog könnte beispielsweise kontobezogenen Code im Paket users und Beiträge betreffenden Code im Paket posts ablegen. Das ist eine gewöhnliche Gliederung innerhalb eines Prozesses: Beide Pakete können als Teile derselben Anwendung laufen und müssen nicht als unabhängige Dienste miteinander kommunizieren.

Ein reguläres Paket enthält üblicherweise eine Datei namens __init__.py. Sie kann leer sein oder ausgewählte Namen als Teil der Paketschnittstelle bereitstellen. Python unterstützt auch Namespace-Pakete, die ohne diese Datei auskommen. Richte dich daher nach dem Paketstil und den Werkzeugen des Projekts, statt __init__.py für universell erforderlich zu halten. Wenn mehrere Bereiche gemeinsamen Code verwenden, lege ihn in einem Modul oder Paket ab, anstatt dasselbe Verhalten in mehreren Verzeichnissen zu duplizieren.

Ergänze Tests, Dokumentation und Webressourcen nach Bedarf

Ein Verzeichnis tests hält automatisierte Prüfungen vom Anwendungscode getrennt. Tests sind auch in kleinen Projekten nützlich: Sie erleichtern es, das erwartete Verhalten bei Änderungen am Code zu überprüfen. Ein Verzeichnis docs kann ausführlichere Anleitungen für Nutzende oder Mitwirkende aufnehmen, wenn eine README nicht mehr ausreicht.

Webprojekte haben häufig ein Verzeichnis templates für HTML, das die Anwendung rendert, und ein Verzeichnis static für Ressourcen wie CSS, JavaScript und Bilder. Wo genau diese Verzeichnisse liegen, hängt vom Framework und seiner Konfiguration ab. Ein Befehlszeilenprogramm ohne Weboberfläche benötigt sie in der Regel nicht.

Datenbankmodelle gehören an die Stelle, die zur gewählten Architektur passt. Ein Projekt kann dafür ein eigenes Modul wie models.py oder ein Paket für mehrere Modellgruppen verwenden. Eine Datei wie database.db ist nur dann sinnvoll, wenn die Anwendung tatsächlich eine lokale dateibasierte Datenbank wie SQLite verwendet. Füge keine Datenbankdatei zur Quellstruktur hinzu, nur weil die Anwendung Daten an anderer Stelle speichert.

Beispiel: eine kleine Bloganwendung

Dieser Blog hält den Code für Konten und Beiträge in getrennten Paketen und legt ausschließlich fürs Web benötigte Ressourcen sowie unterstützende Projektdateien im Stammverzeichnis ab. Die Verzeichnisstruktur ist ein Ausgangspunkt: Je nach Konventionen des Frameworks können Vorlagen, Modelle oder statische Dateien an anderer Stelle liegen. Die Datenbankdatei ist für eine lokale SQLite-Konfiguration vorgesehen; die lokale virtuelle Umgebung bleibt bewusst außerhalb der versionierten Projektstruktur.

Führe dieses Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

layout = [
    "blog/",
    "├── README.md",
    "├── LICENSE",
    "├── pyproject.toml",
    "├── blog/",
    "│   ├── __init__.py",
    "│   ├── users/",
    "│   └── posts/",
    "├── templates/",
    "├── static/",
    "├── tests/",
    "└── database.db  (local SQLite only)",
]
print("\n".join(layout))
blog/
├── README.md
├── LICENSE
├── pyproject.toml
├── blog/
│   ├── __init__.py
│   ├── users/
│   └── posts/
├── templates/
├── static/
├── tests/
└── database.db  (local SQLite only)

Die Beispielstruktur lässt Bereitstellungskonfiguration und Frameworkdetails außen vor. Passe sie daher an die von dir verwendeten Werkzeuge an. Lege Dateien wie models.py im Paket ab, das für die Daten zuständig ist, oder erweitere ein Paket, wenn es wächst. Bei einem Befehlszeilenprojekt kannst du die Webverzeichnisse weglassen; bei einem Datenbankdienst entfällt die lokale Datenbankdatei. Behalte bei der Weiterentwicklung denselben Grundsatz bei: Jedes Verzeichnis sollte dabei helfen, zusammengehörigen Code oder Ressourcen zu finden.