Qual è la migliore struttura di progetto per un'applicazione Python?[chiuso]
-
08-07-2019 - |
Domanda
Immaginate che si desidera sviluppare un banale utente finale desktop (non web) applicazione in Python.Qual è il modo migliore per strutturare il progetto gerarchia di cartelle?
Caratteristiche desiderabili sono la facilità di manutenzione, IDE-compatibilità, idoneità per il controllo di origine ramificazione/fusione, e facile generazione di pacchetti di installazione.
In particolare:
- Dove la metti la fonte?
- Dove la metti applicazione di script di avvio?
- Dove si inserisce il progetto IDE "spazzatura"?
- Dove si fa a mettere l'unità/il test di accettazione?
- Dove la metti non Python dati come file di configurazione?
- Dove la metti non Python fonti come il C++ per il pyd/in modo binario moduli di estensione?
Soluzione
Non troppo importa.Ciò che rende felici di lavoro.Non ci sono un sacco di stupide regole perché Python progetti possono essere semplici.
/scripts
o/bin
per che tipo di interfaccia della riga di comando roba/tests
per i test/lib
per il linguaggio C-librerie/doc
per la maggior parte della documentazione/apidoc
per il Epydoc generato API docs.
E la directory di livello superiore può contenere i README, configurazione e quant'altro.
La difficile scelta se utilizzare o meno un /src
albero.Python non hanno una distinzione tra /src
, /lib
, e /bin
come Java o C è.
Dal momento che un livello superiore /src
directory è visto da alcuni come privo di senso, il top a livello di directory può essere il top a livello di architettura dell'applicazione.
/foo
/bar
/baz
Io consiglio di mettere tutti sotto il "nome-del-mio-prodotto" directory.Quindi, se si sta scrivendo un'applicazione denominata quux
, la directory che contiene tutta questa roba è denominato /quux
.
Un altro progetto PYTHONPATH
, quindi, possono includere /path/to/quux/foo
per riutilizzare il QUUX.foo
modulo.
Nel mio caso, dal momento che io uso Komodo Edit, il mio IDE cuft è un singolo .KPF file.In realtà ho messo nella top-level /quux
directory e omettere l'aggiunta di SVN.
Altri suggerimenti
Secondo Jean-Paul Calderone del Struttura del Filesystem di un progetto di Python:
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
Questo post del blog da Jean-Paul Calderone è comunemente dato come una risposta a #python su Freenode.
Struttura del Filesystem di un progetto di Python
Fare:
- il nome della directory qualcosa legato al tuo progetto.Per esempio, se il progetto è denominato "Twisted", il nome della directory di livello superiore per i file di origine
Twisted
.Quando si fare una release, si consiglia di includere un numero di versione suffisso:Twisted-2.5
.- creare una directory
Twisted/bin
e metti il tuo file eseguibili, se avete qualche.Non dare loro un.py
estensione, anche se sono Python file di origine.Non mettere il codice in loro, eccetto per l'importazione e la chiamata alla funzione definita da qualche altra parte nei vostri progetti.(Lieve grinza:dato che su Windows, l'interprete è selezionato dall'estensione del file, Windows gli utenti in realtà non desidera .py estensione.Così, quando si crea un pacchetto per Windows, è possibile che si desidera aggiungere.Purtroppo non è facile distutils trucco che non conosco per automatizzare questo processo.Considerando che su sistemi POSIX l' .py estensione è solo una verruca, mentre su Windows la mancanza è un bug, se il tuo userbase include gli utenti di Windows, si consiglia di optare per la .py estensione ovunque.)- Se il vostro progetto è expressable come una singola sorgente Python file, poi messo dentro la directory e il nome è qualcosa legato al tuo progetto.Per esempio,
Twisted/twisted.py
.Se avete bisogno di più file di origine, per creare un pacchetto invece (Twisted/twisted/
, vuotoTwisted/twisted/__init__.py
) e inserire i file di origine in esso.Per esempio,Twisted/twisted/internet.py
.- mettere il vostro test di unità in un sub-pacchetto pacchetto (nota: questo significa che la singola sorgente Python file di opzione di cui sopra è un trucco - si sempre bisogno di almeno un altro file per il test di unità).Per esempio,
Twisted/twisted/test/
.Naturalmente, fare un pacchetto conTwisted/twisted/test/__init__.py
.Luogo prove di file, comeTwisted/twisted/test/test_internet.py
.- aggiungere
Twisted/README
eTwisted/setup.py
per spiegare e installare il software, rispettivamente, se ti senti bella.Non:
- mettere la vostra fonte in una directory chiamata
src
olib
.Questo rende difficile eseguito senza installazione.- mettere il test al di fuori del vostro pacchetto Python.Questo rende difficile per eseguire i test, contro una versione installata.
- creare un pacchetto che solo ha un
__init__.py
e poi mettere tutto il codice in__init__.py
.Basta fare un modulo invece di un pacchetto, è più semplice.- provate a venire con magica hack per rendere Python in grado di importare il modulo o pacchetto senza avere l'utente di aggiungere le directory che contengono al loro percorso di importazione (via PYTHONPATH o qualche altro meccanismo).Si non gestire correttamente tutti i casi e gli utenti potranno ottenere arrabbiato con te quando il software non funziona nel loro ambiente.
Check out L'Open source Python Progetto nel Modo Giusto.
Fammi estratto il layout di progetto parte di questo ottimo articolo:
Durante l'impostazione di un progetto, il layout (o la struttura di directory) è importante per ottenere il diritto.Un ragionevole layout significa che i potenziali contribuenti non devono spendere per sempre a caccia di un pezzo di codice;posizioni dei file sono intuitivi.Dal momento che abbiamo a che fare con un progetto esistente, significa che probabilmente avrete bisogno di spostare un po ' di roba in giro.
Partiamo dall'alto.La maggior parte dei progetti hanno un numero di file di livello superiore (come setup.py, LEGGIMI.md, requirements.txt, etc).Ci sono quindi tre le directory che ogni progetto dovrebbe avere:
- Una directory docs contenente la documentazione di progetto
- Una directory denominata con il nome del progetto, che memorizza l'attuale pacchetto Python
- Un test directory in uno dei due posti
- Sotto la directory del pacchetto contenente il codice di test e risorse
- Come stand-alone directory di livello superiore Per ottenere un migliore senso di come i file devono essere organizzati, ecco una semplificato istantanea del layout per uno dei miei progetti, 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
Come potete vedere, ci sono alcuni top a livello di file, una directory docs (generato è una directory vuota dove sfinge metterà la documentazione generata), un sandman directory, e un test di directory in sandman.
Il "Pitone Imballaggio Autorità" ha un sampleproject:
https://github.com/pypa/sampleproject
Si tratta di un progetto di esempio che esiste come un aiuto per il Python Packaging Guida Utente del Tutorial su Confezionamento e la Distribuzione di Progetti.
Provare ad avviare il progetto utilizzando il python_boilerplate modello.Si segue in larga misura la best practice (ad es. quelli qui), ma è più adatto in caso ti ritrovi disposti a dividere il progetto in più di un uovo a un certo punto (e mi creda, con qualsiasi cosa, ma i progetti più semplici, si.Una situazione comune è dove è necessario utilizzare una localmente, e la versione modificata di qualcun altro library).
Dove la metti la fonte?
- Per decentemente grandi progetti ha senso dividere la fonte in più uova.Ogni uovo andrebbe come un separato setuptools-layout di sotto
PROJECT_ROOT/src/<egg_name>
.
- Per decentemente grandi progetti ha senso dividere la fonte in più uova.Ogni uovo andrebbe come un separato setuptools-layout di sotto
Dove la metti applicazione di script di avvio?
- L'opzione ideale è avere applicazione script di avvio registrato come un
entry_point
in una delle uova.
- L'opzione ideale è avere applicazione script di avvio registrato come un
Dove si inserisce il progetto IDE "spazzatura"?
- Dipende dall'IDE.Molti di loro continuano il loro roba in
PROJECT_ROOT/.<something>
nella root del progetto, e questo è bene.
- Dipende dall'IDE.Molti di loro continuano il loro roba in
Dove si fa a mettere l'unità/il test di accettazione?
- Ogni uovo ha una serie di test, conservato nel suo
PROJECT_ROOT/src/<egg_name>/tests
directory.Personalmente preferisco utilizzarepy.test
per la loro esecuzione.
- Ogni uovo ha una serie di test, conservato nel suo
Dove la metti non Python dati come file di configurazione?
- Dipende.Ci possono essere diversi tipi di non-Python dati.
- "Le risorse", cioèi dati che devono essere inseriti all'interno di un uovo.Questo dato va nella corrispondente uovo directory, da qualche parte all'interno del pacchetto di spazio dei nomi.Può essere usato via
pkg_resources
pacchetto. - "Config-files", cioènon Python file che devono essere considerati esterni al progetto i file di origine, ma deve essere inizializzato con alcuni valori quando si avvia l'applicazione in esecuzione.Durante lo sviluppo, preferisco mantenere il file in
PROJECT_ROOT/config
.Per la distribuzione ci possono essere diverse opzioni.Su Windows si può utilizzare%APP_DATA%/<app-name>/config
, su Linux,/etc/<app-name>
o/opt/<app-name>/config
. - I file generati, cioèi file che possono essere creati o modificati dall'applicazione durante l'esecuzione.Preferirei tenerli in
PROJECT_ROOT/var
durante lo sviluppo, e sotto/var
durante la distribuzione di Linux.
- "Le risorse", cioèi dati che devono essere inseriti all'interno di un uovo.Questo dato va nella corrispondente uovo directory, da qualche parte all'interno del pacchetto di spazio dei nomi.Può essere usato via
- Dipende.Ci possono essere diversi tipi di non-Python dati.
- Dove la metti non Python fonti come il C++ per il pyd/in modo binario moduli di estensione?
- In
PROJECT_ROOT/src/<egg_name>/native
- In
La documentazione, in genere, andare in PROJECT_ROOT/doc
o PROJECT_ROOT/src/<egg_name>/doc
(questo dipende se si considerano alcune delle uova per progetti di grandi dimensioni).Alcuni di configurazione aggiuntive saranno in file come PROJECT_ROOT/buildout.cfg
e PROJECT_ROOT/setup.cfg
.
Nella mia esperienza, è solo una questione di iterazione.Inserire i tuoi dati e il codice dove si pensa di andare.Le probabilità sono, sarete sbagliato comunque.Ma una volta che si ottiene una migliore idea di come le cose stanno andando a prendere forma, sei in una posizione molto migliore per fare questo tipo di ipotesi.
Quanto fonti di estensione, abbiamo un Codice di directory in tronco che contiene una directory per python e una directory per varie altre lingue.Personalmente sono più propenso a provare a mettere il codice di estensione nei propri repository per la prossima volta.
Detto questo, torno al mio punto iniziale:non fare un grande affare fuori di esso.Mettere da qualche parte che sembra funzionare per voi.Se trovate qualcosa che non funziona, può (e dovrebbe) essere cambiato.
Non python i dati in bundle all'interno del vostro moduli Python utilizzando il package_data
supporto in setuptools.Una cosa che consiglio caldamente è using namespace pacchetti per la creazione condivisa di spazi dei nomi che più progetti possibile utilizzare, come Java convenzione di mettere i pacchetti in com.yourcompany.yourproject
(e di essere in grado di avere una condivisa com.yourcompany.utils
spazio dei nomi).
Re ramificazione e la fusione, se si utilizza una buona fonte sistema di controllo in grado di gestire unisce anche attraverso rinomina; Bazar è particolarmente bravo in questo.
Al contrario di alcune altre risposte qui, sto +1 su un src
directory di livello superiore (con doc
e test
directory fianco).Convenzioni specifiche per la documentazione alberi di directory variano a seconda di quello che stai utilizzando; Sfinge, per esempio, ha le proprie convenzioni che la sua quickstart strumento supporta.
Per favore, per favore leva setuptools e pkg_resources;questo rende molto più facile per gli altri progetti si basano su versioni specifiche del codice (e per di più versioni contemporaneamente installato con diverse camere non-file di codice, se si sta utilizzando package_data
).