Gute Verzeichnisstruktur?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute,

ich bin gerade dabei meine Verzeichnisstruktur zu überdenken, und bräuchte dabei euren Rat. Immerhin habt ihr einige Projekte geschrieben und könnt mir dann sagen, welche Struktur sich am besten einigt. Wie ich auf diese Fragestellung kommt erkläre ich später. Zunächst einmal möchte ich euch meine bisherige Struktur vorstellen.

Elternverzeichnis
Bild
Im Ordner licences wird die Text-Datei der GPL2-Lizenz gespeichert, die dann auch im Programm geöffnet wird. In settins werden die Einstellungs-Datei (config.ini) gespeichert. Ich möchte diese Einstellungs-Datei "außerhalb" der Module speichern. Warum? Der Anwender soll seine Einstellungs-Datei schnell finden, ohne in den anderen Dateien rumwuschen zu müssen. Und in temp soll die heruntergeladene Datei zunächst zwischengespeichert werden. Ich denke da zum Beispiel an Updates. Und in files sind die Module, GUI-Dateien etc - also das Herzstück des "Projektes". Und zum Schluss sehen wir noch drei einzelne Dateien: xarphus.bat, xarphus.py und xarphus.pyw. Ich denke da eher an Web-Programmierung. Man hat da immer eine Art Index-Datei, von dort aus wird das Programm also gestartet.

Strukturierung
Bild
Hier dachte ich kategorisiere ich einfach. Die ui-Dateien (GUI) kommen in den Ordner qt-ui, und die UI-Klassen kommen dann in modules_ui, und "normale" Module, in denen Funktionen sind, kommen dann in modules, die Bilder kommen dann in images, in about steckt ein Modul, in welcher Informationen über die Anwendung steht - in Form von Dictionaries und dann noch languages - dort kommen die Sprachen rein.

Wie komme ich nun dazu, dass ich mein Verzeichnis überdenken möchte?

Nun, nehmen wir mal an, ich möchte in der GUI-Klasse ui_pp_about.py (dieses Modul ist im Ordner modules_ui) etwas importieren. Sagen wir, ich möchte ein Modul laden, in denen die Einstellungen in Form von Dictionaries gespeichert sind. Ich spreche hier von mod_Setting.py, dieses Modul liegt um Verzeichnis modules.

Dies würde dann bei mir wie folgt aussehen:

ui_pp_about.py

Code: Alles auswählen

from ..modules.mod_Settings import Configuration
Und ich weiß nicht wer mich darauf hingewiesen hat - ich glaube Hyperion war es. Aber irgendwie kommt mir das mit den beiden Punkte "komisch" vor - also dieses from ... .Oder ist dies insofern normal, dass es öfters vorkommt oder vermeidet man am besten solch eine Situation bzw. solch eine Struktur?
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für meinen Geschmack übertreibst du es ein bißchen mit den Unterverzeichnissen. Wenn man ein Verzeichnis hat, wo nur eine Datei drinliegt, dann ist es meistens besser, die Datei direkt abzulegen, also ohne sie in einen eigenen Ordner zu stecken.

Auch die Namensgebung ist komisch: Vor Modulverzeichnisse schreibt man normalerweise nicht extra ein "mod_". Und statt "ui_about.py" kann man auch einfach eine "about.py" ins "ui"-Verzeichnis ablegen. Wieviele Lizenzen hat dein Modul eigentlich? Braucht es dafür wirklich einen eigenen "licences"-Ordner? Und "files" ist als Ordername total nichtssagend. Ein Dritter wüsste wohl kaum, was damit gemeint ist.

Und auch ich stolpere über das ``from ..modules.mod_Settings import Configuration``. Dass man sich soweit durch die interne Struktur hangeln muss, ist meistens kein so gutes Zeichen. Manchmal kann man das sinnvoll lösen, wenn man im Elternverzeichnis in der ``__init__.py`` einige wichtige Bezeichner aus den Untermodulen durch Import quasi nach oben holt. Dann müssen Module, die aus einer ganz anderen Ecke kommen, nicht mehr soviel Wissen über die interne Struktur anderer Pakete haben.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

snafu hat geschrieben: Und auch ich stolpere über das ``from ..modules.mod_Settings import Configuration``. Dass man sich soweit durch die interne Struktur hangeln muss, ist meistens kein so gutes Zeichen. Manchmal kann man das sinnvoll lösen, wenn man im Elternverzeichnis in der ``__init__.py`` einige wichtige Bezeichner aus den Untermodulen durch Import quasi nach oben holt. Dann müssen Module, die aus einer ganz anderen Ecke kommen, nicht mehr soviel Wissen über die interne Struktur anderer Pakete haben.
Wie würde das konkret aussehen? Du hast vielleicht Recht. Vielleicht übertreibe ich es ein Bisschen mit den Unterverzeichnissen. Jedoch bin ich ein Mensch, der nicht erst hinterher die Verzeichnisstruktur ummodeln will, wenn man merkt "Oh, mein kleines Projekt nimmt langsam Züge an", sondern möchte gleich im Vorfeld quasi die Weichen stellen, damit ich nicht hinterher alles erledigen muss. Ich bin leider kein Freund von Verzeichnissen, wenn alle Dateien in einem Ordner gestopft werden. Ich wollte da ein wenig "Ordnung" reinbringen. Und das führt dazu, dass ich mich dann durch die innere Struktur hangeln muss, bis ich an ein Modul komme bzw. ein Modul importieren kann.

Bei der Strukturierung habe ich mich damals an diese Dokumentation gehalten. Scroll soweit runter, bis du an dem Punkt 6.4 Packages gelangt bist. Wenn man sich diese Struktur anschaut, müsste man sich auch ganz schön weit durch die interne Struktur hangeln?
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:
snafu hat geschrieben:Und auch ich stolpere über das ``from ..modules.mod_Settings import Configuration``. (...)
Wie würde das konkret aussehen?
Ich würde an deiner Stelle die komplette Struktur umwürfeln. Ein Ordner "modules" im obersten Verzeichnis des Projekts ist ja noch okay (manche nennen sowas "src" oder nehmen den Projektnamen). Dann als Unterverzeichnisse einfach sowas wie "core" und "gui", die entsprechend als Python-Packages eingesetzt werden sollen. Die "settings.py" könnte man - da sie vermutlich von beiden Packages verwendet wird - direkt im "modules"-Ordner ablegen. Dann wäre obiger Import ein ``from ..settings import Configuration``, was nicht mehr ganz so wild aussähe.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@snafu: Wenn ich dich richtig verstehe:

xarphus_project <-- Elternverzeichnis
xarphus.py
xarphus.pyw
xarphus.bat
... files
...... src <-- (sämtliche Module)
...... __init__.py
......... ui <-- (ui-Dateien und auch ui-Klassen)
...... __init__.py
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:Bei der Strukturierung habe ich mich damals an diese Dokumentation gehalten. Scroll soweit runter, bis du an dem Punkt 6.4 Packages gelangt bist. Wenn man sich diese Struktur anschaut, müsste man sich auch ganz schön weit durch die interne Struktur hangeln?
Natürlich müsste man das. Für mich persönlich beginnt es ab dem Punkt schlechter Stil zu werden, an dem ein Import sich mittels ``..`` aus "seinem" Bereich raushangelt und dann relativ weit in die Struktur eines anderen Packages eindringt.

Soll sagen: Eine Abhängigkeit nach unten hin ist okay (also: Elternverzeichnis holt sich was aus Unterverzeichnis), aber eine horizontale Abhängigkeit (= Elternverzeichnis A nimmt was aus Elternverzeichnis B) finde ich meistens ungünstig.

Ich will nicht sagen, dass Package A niemals Package B befragen soll. Aber es sollte halt im Rahmen bleiben. Zum Teil kann man seine Struktur auch so bauen, dass Package A genau wie Package B nur über ein Hilfsmodul miteinander kommunizieren, welches oberhalb von den beiden angesiedelt ist. Das würde ich aber erst machen, wenn es sehr unübersichtlich wird.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:@snafu: Wenn ich dich richtig verstehe:

xarphus_project <-- Elternverzeichnis
xarphus.py
xarphus.pyw
xarphus.bat
... files
...... src <-- (sämtliche Module)
...... __init__.py
......... ui <-- (ui-Dateien und auch ui-Klassen)
...... __init__.py
Den Zwischenschritt mit "files" würde ich weglassen. Wo soll da der Mehrwert liegen? Und in "src" dann:

src
... core (Verzeichnis)
... gui (Verzeichnis)
... __init__.py
... settings.py
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@snafu: Mit anderen Worte: Die in er Dokumentation dargestellte Struktur wäre ein schlechter Stil?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@snafu: Der vollständigkeitshalber:

xarphus_project <-- Elternverzeichnis
xarphus.py (Datei)
xarphus.pyw (Datei)
xarphus.bat (Datei)
... src (1. Unterverzeichnis)
... __init__.py
...... core (2. Unterverzeichnis)
...... __init__.py
......... gui (3. Unterverzeichnis)
......... __init__.py
---------------------------------------------
In src kommen alle Module rein.
In core kommt was rein?
In gui kommen ui-Dateien rein, die dynamisch geladen werden.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:@snafu: Mit anderen Worte: Die in er Dokumentation dargestellte Struktur wäre ein schlechter Stil?
Finde ich nicht. Da kommt auch nichts vor, was ich hier als schlechten Stil eingeordnet habe. Worauf beziehst du dich denn konkret?
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:@snafu: Der vollständigkeitshalber:

xarphus_project <-- Elternverzeichnis
xarphus.py (Datei)
xarphus.pyw (Datei)
xarphus.bat (Datei)
... src (1. Unterverzeichnis)
... __init__.py
...... core (2. Unterverzeichnis)
...... __init__.py
......... gui (3. Unterverzeichnis)
......... __init__.py
Jetzt sieht es so aus als wenn "gui" ein Untermodul von "core" ist. Mein Vorschlag war aber, dass "core", "gui" und "settings.py" auf der selben Ebene existieren.
Sophus hat geschrieben:In src kommen alle Module rein.
In core kommt was rein?
In gui kommen ui-Dateien rein, die dynamisch geladen werden.
In "src" alle Module (bzw diejenigen, die in keinen Unterordner gesteckt wurden), in "gui" alles für die grafische Oberfläche, in "core" alles für die interne Logik deines Programms.

"core" sollte ohne "gui" funktionieren können. Nur "gui" ist abhängig von "core". Damit könnte man auch das GUI-Framework austauschen, ohne was an "core" ändern zu müssen. Man könnte auch eine kommandozeilenbasierte Oberfläche entwerfen, die sich alles nötige aus dem "core"-Package holt.
Zuletzt geändert von snafu am Dienstag 5. Mai 2015, 21:57, insgesamt 1-mal geändert.
BlackJack

@Snafu: Sehe ich das richtig das Du ein *Package* `src` nennst? Ich würde diesen ganzen generischen Verzeichnisnamen-Unsinn sein lassen und dem Package einen vernünftigen Namen geben. Auf oberster Ebene des Projekts. Es sei denn das Projekt hätte mehr als ein Top-Level-Package. Wobei das dann vielleicht auch besser mehrere Projekte wären, beziehungsweise würde dann wahrscheinlich ein Namespace-Package Sinn machen.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@BlackJack: Ich würde da eher den Namen meines Projektes verwenden. Da Sophus bei seinen letzten Beiträgen "src" gewählt hatte, habe ich dies so übernommen.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@snafu: Ich beziehe mich hierauf.

Und die ui-Klassen würdest du wohin packen? Auch in den GUI-Order oder in den src-Ordner? Denn im core-Ordner hätten die ja nichts zu suchen?
------------------------------------

xarphus_project <-- (Top-Level - Name des Projektes)
xarphus.py (Datei)
xarphus.pyw (Datei)
xarphus.bat (Datei)
... src (1. Unterverzeichnis)
... __init__.py
...... core (2. Unterverzeichnis)
...... __init__.py
...... gui (3. Unterverzeichnis)
...... __init__.py
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:@snafu: Ich beziehe mich hierauf.
Den Link hattest du ja schon zuvor geliefert. Ich sehe da lediglich eine tiefe Ordnerstruktur, die über mehrere Packages verteilt ist. Inwiefern machst du jetzt fest, dass ich dies für schlechten Stil halte? Das tue ich nämlich nicht. Gegen das grundsätzliche Vorhandensein einer solchen Struktur habe ich nichts einzuwenden. Es ging mir nur um die Art, wie man mit Imports aus anderen Packages umgeht. Das war ja auch von Anfang an Thema des Threads. Zumindest habe ich das so verstanden.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@snafu: Es ging mir sowohl um die Ordnerstruktur als auch um die Imports.

Würde ich die Dokumentation bis zum Ende Verfolgen:

Code: Alles auswählen

from . import echo
from .. import formats
from ..filters import equalizer
Könnten die Imports am Ende auch so aussehen. Also auch sehr holprig?
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sophus hat geschrieben:

Code: Alles auswählen

from . import echo
from .. import formats
from ..filters import equalizer
Könnten die Imports am Ende auch so aussehen. Also auch sehr holprig?
Naja, wenn man ein Programm zur Soundbearbeitung hat und die verschiedenen Kompenenten dann z.B in einer GUI zusammenfügen möchte, dann sollte es IMHO halt ein Package geben, wo die ganzen Komponenten definiert werden und ein Modul, das entweder auf der selben Ebene wie das Komponenten-Package oder auf einer darüberliegenden Ebene angesiedelt ist. Dieses Modul importiert dann die benötigen Komponenten. Dann braucht es auch keine ".."-Importe. Und die werden in dem verlinkten Teil der Doku ja auch gar nicht angewendet.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@snafu:

Wie gesagt, ich habe mich erst einmal an deinem Ratschlag befolgt und das Ganze wie folgt umgesetzt:

xarphus_project <-- (Top-Level - Name des Projektes)
xarphus.py (Datei)
xarphus.pyw (Datei)
xarphus.bat (Datei)
... src (1. Unterverzeichnis)
... __init__.py
...... core (2. Unterverzeichnis)
...... __init__.py
...... gui (3. Unterverzeichnis)
...... __init__.py

Aber meine Frage: Die Ui-Module würdest du dann in den src-Ordner verlegen, richtig? Mit UI-Module meine ich jene Module wo man die ui-Dateien dynamisch lädt, und bestimmte Actionen festlegt etc.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, die entsprechenden Python-Module würde ich in "src/gui" legen.

So Sachen wie Grafiken oder Dateien vom Qt-Designer kämen in ein extra "ressources"-Verzeichnis oder direkt als "icons", "ui" usw ohne den Zwischenschritt über "ressources" - je nachdem, wieviel das ist. Ich meine damit also die Dateien, die nicht pythonspezifisch sind.
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: ich sehe in Deiner ganzen Struktur noch gar kein setup.py? Warum gibt es ein xarphus.py und ein xarphus.pyw und ein xarphus.bat? Für ein GUI-Programm würde die pyw-Datei reichen, dann weiß man wenigstens gleich, welche man aufrufen soll. Würdest Du Deinen Paketen ordentliche Namen geben, würdest Du Dich vielleicht auch weniger gegen absolute Importe wehren. Ein Verzeichnis das files oder src heißt, sollte kein __init__.py haben, weil ich will ja nichts from src.xyz importieren. Ich würde ja eine xarphus_main.pyw im Stammverzeichnis haben, und alle restlichen Python-Dateien in ein xarphus-Paket stecken, das vielleicht, je nach Größe des Projekts in Unterpakete gui (alles was mit GUI zu tun hat) und andere Namen (nicht gerade core, das ist auch zu nichtssagend) von relativ selbständigen Teilen, die aber nichts mit gui zu tun haben. Auf oberster Ebene liegen neben der pyw-Datei noch eine README, LICENCE, settings.ini und wenn man das von den py-Dateien trennen will, ein resources-Verzeichnis, in dem Bilder, ui-Dateien und ähnliches liegt. Ganz wichtig, ein Verzeichnis test, in dem alle unit-Test-Dateien in einer ähnlichen Struktur wie im xarphus-Verzeichnis liegen.
Antworten