it-swarm.com.de

Was ist die beste Projektstruktur für eine Python -Anwendung?

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:

  1. Woher nimmst du die Quelle?
  2. Wo legen Sie Anwendungsstartskripte ab?
  3. Wo haben Sie das Projekt cruft IDE abgelegt?
  4. Wo legen Sie die Geräte-/Abnahmeprüfungen ab?
  5. Wo legen Sie Nicht-Python-Daten wie Konfigurationsdateien ab?
  6. Wo legen Sie Nicht-Python-Quellen wie C++ für pyd/so-Binärerweiterungsmodule ab?
674
kbluck

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.

347
S.Lott

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
226
cmcginty

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 leeren Twisted/twisted/__init__.py) und platzieren Sie Ihre Quelldateien darin. Zum Beispiel Twisted/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 mit Twisted/twisted/test/__init__.py. Platzieren Sie Tests in Dateien wie Twisted/twisted/test/test_internet.py.
  • fügen Sie Twisted/README und Twisted/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 oder lib. 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.
214
Adrian

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.

107
David C. Bishop

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.

25
guettli

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?

    • Für anständige Großprojekte ist es sinnvoll, die Quelle in mehrere Eier aufzuteilen. Jedes Ei würde als eigenes Setuptools-Layout unter PROJECT_ROOT/src/<Egg_name> abgelegt.
  • Wo platzieren Sie Anwendungsstartskripte?

    • Die ideale Option besteht darin, ein Anwendungsstart-Skript als entry_point in einem der Eier zu registrieren.
  • Wo haben Sie das IDE Projekt cruft abgelegt?

    • Hängt von der IDE ab. Viele von ihnen behalten ihre Sachen in PROJECT_ROOT/.<something> im Stammverzeichnis des Projekts, und das ist in Ordnung.
  • Wo legen Sie die Geräte-/Abnahmeprüfungen ab?

    • Jedes Ei hat eine separate Reihe von Tests, die im Verzeichnis 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?

    • Es hängt davon ab, ob. Es kann verschiedene Arten von Nicht-Python-Daten geben.
      • "Ressourcen" , d. H. Daten, die in ein Ei gepackt werden müssen. Diese Daten werden in das entsprechende Egg-Verzeichnis im Package-Namespace geschrieben. Es kann über das Paket pkg_resources verwendet werden.
      • "Config-files" , d. H. Nicht-Python-Dateien, die als außerhalb der Projektquelldateien befindlich betrachtet werden sollen, jedoch mit einigen Werten initialisiert werden müssen, wenn die Anwendung gestartet wird. Während der Entwicklung bevorzuge ich es, solche Dateien in 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.
      • Erzeugte Dateien , d. H. Dateien, die von der Anwendung während der Ausführung erstellt oder geändert werden können. Ich würde es vorziehen, sie während der Entwicklung in PROJECT_ROOT/var und während der Linux-Bereitstellung unter /var zu belassen.
  • Wo legen Sie Nicht-Python-Quellen wie C++ für pyd/so-Binärerweiterungsmodule ab?
    • In 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.

16
KT.

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.

14
Jason Baker

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).

7
Charles Duffy