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:

  1. Dove la metti la fonte?
  2. Dove la metti applicazione di script di avvio?
  3. Dove si inserisce il progetto IDE "spazzatura"?
  4. Dove si fa a mettere l'unità/il test di accettazione?
  5. Dove la metti non Python dati come file di configurazione?
  6. Dove la metti non Python fonti come il C++ per il pyd/in modo binario moduli di estensione?
È stato utile?

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/, vuoto Twisted/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 con Twisted/twisted/test/__init__.py.Luogo prove di file, come Twisted/twisted/test/test_internet.py.
  • aggiungere Twisted/README e Twisted/setup.py per spiegare e installare il software, rispettivamente, se ti senti bella.

Non:

  • mettere la vostra fonte in una directory chiamata src o lib.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>.
  • 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.
  • 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.
  • 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 utilizzare py.test per la loro esecuzione.
  • 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.
  • 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

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top