Stellen Sie sich vor, Sie möchten eine nicht triviale Endbenutzer-Desktop-Anwendung (keine Webanwendung) in Python entwickeln. Wie lässt sich die Ordnerhierarchie des Projekts am besten strukturieren?
Wünschenswerte Merkmale sind einfache Wartung, IDE-Freundlichkeit, Eignung für das Verzweigen/Zusammenführen von Quellcodeverwaltungen und einfache Generierung von Installationspaketen.
Speziell:
Ist nicht so wichtig. Was auch immer dich glücklich macht, wird funktionieren. Es gibt nicht viele alberne Regeln, da Python Projekte einfach sein können.
/scripts
oder /bin
für diese Art von Kommandozeilen-Interface/tests
für deine Tests/lib
für Ihre C-Sprachbibliotheken/doc
für die meisten Dokumentationen/apidoc
für die von Epydoc generierten API-Dokumente.Und das Hauptverzeichnis kann README's, Config's und so weiter enthalten.
Die schwierige Wahl ist, ob ein /src
-Baum verwendet werden soll oder nicht. Python unterscheidet nicht zwischen /src
, /lib
und /bin
wie Java oder C.
Da ein /src
-Verzeichnis der obersten Ebene von manchen als bedeutungslos angesehen wird, kann Ihr Verzeichnis der obersten Ebene die Architektur Ihrer Anwendung sein.
/foo
/bar
/baz
Ich empfehle, dies alles in das Verzeichnis "name-of-my-product" zu schreiben. Wenn Sie also eine Anwendung mit dem Namen quux
schreiben, heißt das Verzeichnis, das all diese Informationen enthält, /quux
.
Das PYTHONPATH
eines anderen Projekts kann dann /path/to/quux/foo
enthalten, um das QUUX.foo
-Modul wiederzuverwenden.
In meinem Fall ist mein IDE Cuft eine einzelne KPF-Datei, da ich Komodo Edit verwende. Ich habe das tatsächlich in das /quux
-Verzeichnis der obersten Ebene gestellt und das Hinzufügen zu SVN weggelassen.
Nach Jean-Paul Calderones Dateisystemstruktur eines Python-Projekts :
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
Dieser Blog-Beitrag von Jean-Paul Calderone wird häufig in #python auf Freenode als Antwort gegeben.
Dateisystemstruktur eines Python Projekts
Machen:
- nennen Sie das Verzeichnis etwas, das mit Ihrem Projekt zusammenhängt. Wenn Ihr Projekt beispielsweise "Twisted" heißt, benennen Sie das oberste Verzeichnis für die Quelldateien
Twisted
. Wenn Sie Releases erstellen, sollten Sie ein Versionsnummer-Suffix einfügen:Twisted-2.5
.- erstelle ein Verzeichnis
Twisted/bin
und füge deine ausführbaren Dateien dort ein, falls du welche hast. Geben Sie ihnen keine.py
-Erweiterung, auch wenn es sich um Python Quelldateien handelt. Fügen Sie keinen Code ein, außer dem Importieren und Aufrufen einer Hauptfunktion, die an einer anderen Stelle in Ihren Projekten definiert ist. (Leichte Falten: Da unter Windows der Interpreter von der Dateierweiterung ausgewählt wird, möchten Ihre Windows-Benutzer tatsächlich die Erweiterung .py. Wenn Sie also ein Paket für Windows erstellen, möchten Sie diese möglicherweise hinzufügen. Leider gibt es keinen einfachen distutils-Trick Ich weiß, dass ich diesen Prozess automatisieren muss. In Anbetracht dessen, dass die .py-Erweiterung unter POSIX nur eine Warze ist, während das Fehlen unter Windows ein tatsächlicher Fehler ist Erweiterung überall.)- Wenn Ihr Projekt als einzelne Python Quelldatei ausgedrückt werden kann, legen Sie es in das Verzeichnis und nennen Sie es etwas, das mit Ihrem Projekt zusammenhängt. Zum Beispiel
Twisted/twisted.py
. Wenn Sie mehrere Quelldateien benötigen, erstellen Sie stattdessen ein Paket (Twisted/twisted/
mit einem leerenTwisted/twisted/__init__.py
) und platzieren Sie Ihre Quelldateien darin. Zum BeispielTwisted/twisted/internet.py
.- fügen Sie Ihre Komponententests in ein Unterpaket Ihres Pakets ein (Hinweis: Dies bedeutet, dass die oben angegebene Option für die einzelne Python -Quelldatei ein Trick war - Sie immer brauche mindestens eine andere Datei für deine Unit Tests). Zum Beispiel
Twisted/twisted/test/
. Machen Sie es natürlich zu einem Paket mitTwisted/twisted/test/__init__.py
. Platzieren Sie Tests in Dateien wieTwisted/twisted/test/test_internet.py
.- fügen Sie
Twisted/README
undTwisted/setup.py
hinzu, um Ihre Software zu erklären und zu installieren, wenn Sie sich gut fühlen.Nicht:
- legen Sie Ihre Quelle in ein Verzeichnis mit dem Namen
src
oderlib
. Dies macht es schwierig, ohne Installation auszuführen.- legen Sie Ihre Tests außerhalb Ihres Pakets Python ab. Dies macht es schwierig, die Tests für eine installierte Version auszuführen.
- erstellen Sie ein Paket, das nur einen
__init__.py
enthält, und fügen Sie dann Ihren gesamten Code in__init__.py
ein. Erstellen Sie einfach ein Modul anstelle eines Pakets, es ist einfacher.- versuchen Sie, magische Hacks zu entwickeln, mit denen Python Ihr Modul oder Paket importieren kann, ohne dass der Benutzer das Verzeichnis, in dem es sich befindet, seinem Importpfad hinzufügt (entweder über PYTHONPATH oder einen anderen Mechanismus). Sie werden nicht alle Fälle richtig behandeln und Benutzer werden wütend auf Sie, wenn Ihre Software in ihrer Umgebung nicht funktioniert.
Check out Open Sourcing eines Python Projekts auf die richtige Weise .
Lassen Sie mich den Teil des Projektlayouts dieses hervorragenden Artikels ausschneiden:
Beim Einrichten eines Projekts ist es wichtig, dass das Layout (oder die Verzeichnisstruktur) richtig ist. Ein vernünftiges Layout bedeutet, dass potenzielle Mitwirkende nicht ewig nach einem Stück Code suchen müssen. Dateispeicherorte sind intuitiv. Da es sich um ein vorhandenes Projekt handelt, müssen Sie wahrscheinlich einige Dinge verschieben.
Fangen wir oben an. Die meisten Projekte haben eine Reihe von Dateien der obersten Ebene (wie setup.py, README.md, requirements.txt usw.). Es gibt dann drei Verzeichnisse, die jedes Projekt haben sollte:
- Ein docs-Verzeichnis, das die Projektdokumentation enthält
- Ein Verzeichnis mit dem Namen des Projekts, in dem das aktuelle Python -Paket gespeichert ist
- Ein Testverzeichnis an einer von zwei Stellen
- Unter dem Paketverzeichnis mit Testcode und Ressourcen
- Als eigenständiges Verzeichnis der obersten Ebene Um einen besseren Überblick über die Organisation Ihrer Dateien zu erhalten, finden Sie hier eine vereinfachte Momentaufnahme des Layouts für eines meiner Projekte, sandman:
$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
| |-- conf.py
| |-- generated
| |-- index.rst
| |-- installation.rst
| |-- modules.rst
| |-- quickstart.rst
| |-- sandman.rst
|- requirements.txt
|- sandman
| |-- __init__.py
| |-- exception.py
| |-- model.py
| |-- sandman.py
| |-- test
| |-- models.py
| |-- test_sandman.py
|- setup.py
Wie Sie sehen, gibt es einige Dateien der obersten Ebene, ein docs-Verzeichnis (generiert ist ein leeres Verzeichnis, in das Sphinx die generierte Dokumentation legt), ein sandman-Verzeichnis und ein Testverzeichnis unter sandman.
Die "Python Packaging Authority" hat ein Beispielprojekt:
https://github.com/pypa/sampleproject
Es handelt sich um ein Beispielprojekt, das als Hilfe für das Lernprogramm zum Verpacken und Verteilen von Projekten im Python Packaging-Benutzerhandbuch vorhanden ist.
Starten Sie das Projekt mit der Vorlage python_boilerplate . Es folgt größtenteils den Best Practices (z. B. die hier ), ist jedoch besser geeignet, wenn Sie bereit sind, Ihr Projekt irgendwann in mehr als ein Ei aufzuteilen (und glauben Sie mir, mit irgendetwas anderem als dem Sie werden es mit den einfachsten Projekten zu tun haben. In der Regel müssen Sie eine lokal geänderte Version der Bibliothek eines anderen Benutzers verwenden.
Woher nimmst du die Quelle?
PROJECT_ROOT/src/<Egg_name>
abgelegt.Wo platzieren Sie Anwendungsstartskripte?
entry_point
in einem der Eier zu registrieren.Wo haben Sie das IDE Projekt cruft abgelegt?
PROJECT_ROOT/.<something>
im Stammverzeichnis des Projekts, und das ist in Ordnung.Wo legen Sie die Geräte-/Abnahmeprüfungen ab?
PROJECT_ROOT/src/<Egg_name>/tests
gespeichert sind. Ich persönlich bevorzuge es, py.test
zu verwenden, um sie auszuführen.Wo werden Nicht-Python-Daten wie Konfigurationsdateien abgelegt?
pkg_resources
verwendet werden.PROJECT_ROOT/config
zu speichern. Für den Einsatz gibt es verschiedene Möglichkeiten. Unter Windows kann man %APP_DATA%/<app-name>/config
, unter Linux /etc/<app-name>
oder /opt/<app-name>/config
verwenden.PROJECT_ROOT/var
und während der Linux-Bereitstellung unter /var
zu belassen.PROJECT_ROOT/src/<Egg_name>/native
Die Dokumentation wird normalerweise in PROJECT_ROOT/doc
oder PROJECT_ROOT/src/<Egg_name>/doc
geschrieben (dies hängt davon ab, ob Sie einige der Eier als separate Großprojekte ansehen). Einige zusätzliche Konfigurationen sind in Dateien wie PROJECT_ROOT/buildout.cfg
und PROJECT_ROOT/setup.cfg
enthalten.
Nach meiner Erfahrung ist es nur eine Frage der Iteration. Platzieren Sie Ihre Daten und Ihren Code, wo immer Sie glauben, dass sie sich befinden. Wahrscheinlich irren Sie sich trotzdem. Aber sobald Sie eine genauere Vorstellung davon haben, wie sich die Dinge entwickeln werden, sind Sie in einer viel besseren Position, um solche Vermutungen anzustellen.
In Bezug auf Erweiterungsquellen haben wir ein Codeverzeichnis unter trunk, das ein Verzeichnis für python und ein Verzeichnis für verschiedene andere Sprachen enthält. Persönlich bin ich eher geneigt, beim nächsten Mal einen beliebigen Erweiterungscode in ein eigenes Repository zu stellen.
Vor diesem Hintergrund komme ich zu meinem ursprünglichen Punkt zurück: Machen Sie keine allzu großen Dinge daraus. Stellen Sie es irgendwo hin, wo es für Sie zu funktionieren scheint. Wenn Sie etwas finden, das nicht funktioniert, kann (und sollte) es geändert werden.
Nicht-Python-Daten werden am besten in Ihren Python - Modulen gebündelt, indem die Unterstützung von _package_data
_ in setuptools verwendet wird. Ich empfehle dringend, Namespace-Pakete zu verwenden, um gemeinsam genutzte Namespaces zu erstellen, die von mehreren Projekten verwendet werden können - ähnlich wie die Konvention Java, Pakete in _com.yourcompany.yourproject
_ zu platzieren (und in der Lage zu sein, ein gemeinsam genutztes _com.yourcompany.utils
_ Namespace).
Erneutes Verzweigen und Zusammenführen: Wenn Sie ein ausreichend gutes Quellcodeverwaltungssystem verwenden, werden Zusammenführungen auch durch Umbenennen verarbeitet. Basar ist besonders gut darin.
Im Gegensatz zu einigen anderen Antworten habe ich +1 für ein src
-Verzeichnis auf oberster Ebene (mit doc
und test
-Verzeichnissen daneben). Die spezifischen Konventionen für Dokumentationsverzeichnisbäume variieren je nachdem, was Sie verwenden. Sphinx hat zum Beispiel eigene Konventionen, die das Quickstart-Tool unterstützt.
Bitte nutzen Sie setuptools und pkg_resources. Dies macht es für andere Projekte viel einfacher, sich auf bestimmte Versionen Ihres Codes zu verlassen (und für mehrere Versionen, die gleichzeitig mit verschiedenen Nicht-Code-Dateien installiert werden, wenn Sie _package_data
_ verwenden).