Distribuire un'applicazione Python con pacchetto condiviso
-
11-07-2019 - |
Domanda
Sto pensando a come organizzare un'applicazione Python distribuita che avrà un
- Script eseguibile situato in / usr / bin / che fornirà una CLI per le funzionalità implementate in
- Una libreria installata ovunque si trovi l'attuale directory dei pacchetti del sito.
Ora, attualmente, ho la seguente struttura di directory nelle mie fonti:
foo.py
foo/
__init__.py
...
che immagino non sia il modo migliore per fare le cose. Durante lo sviluppo, tutto funziona come previsto, tuttavia, quando distribuito, il "da Foo import FooObject" il codice in foo.py tenta apparentemente di importare foo.py stesso, che non è il comportamento che sto cercando.
Quindi la domanda è qual è la pratica standard di orchestrare situazioni come questa? Una delle cose che mi viene in mente è, durante l'installazione, rinominare foo.py in solo foo, che impedisce di importare se stesso, ma sembra piuttosto imbarazzante ...
Un'altra parte del problema, suppongo, è che è una sfida per i nomi. Forse chiamare lo script eseguibile foo-bin.py?
Soluzione
Questo articolo è abbastanza buono e ti mostra un buon modo per farlo. Il secondo elemento dell'elenco Do risponde alla tua domanda.
copia incolore copia:
Struttura del filesystem di un progetto Python
di Jp Calderone
- dai un nome alla directory in relazione al tuo progetto. Ad esempio, se il tuo il progetto è denominato "Contorto", nome " directory di primo livello per la sua fonte file
Contorto
. Quando rilasci, dovresti includere un numero di versione suffisso:Twisted-2.5
.- crea una directory
Twisted / bin
e inserisci lì i tuoi eseguibili, se lo desideri avere qualche. Non dare loro un.py
estensione, anche se sono Python file sorgenti. Non inserire alcun codice eccetto l'importazione e la chiamata a funzione principale definita altrove nei tuoi progetti.- Se il tuo progetto è espressibile come un singolo file sorgente Python, inseriscilo nella directory e denominarlo qualcosa legato al tuo progetto. Per esempio,
Twisted / twisted.py
. Se tu bisogno di più file di origine, creare un pacchetto invece (Twisted / twisted /
, con un vuotoTwisted / twisted / __ init__.py
) e posizionalo i tuoi file sorgente in esso. Per esempio,ritorto / contorto / internet.py
.- metti i test unitari in un sotto-pacchetto del tuo pacchetto (nota - questo significa che il singolo file sorgente Python l'opzione sopra era un trucco - tu sempre hai bisogno di almeno un altro file per il tuo test unitari). Per esempio,
ritorto / contorto / test /
. Certo, crea un pacchetto conritorto / contorto / test / __ init __. Py
. Collocare test in file comeritorto / contorto / test / test_internet.py
.- aggiungi
Twisted / README
eTwisted / setup.py
per spiegare e installa il tuo software, rispettivamente, se ti senti bene.Non
- metti la tua fonte in una directory chiamata
src
olib
. Questo lo rende difficile eseguire senza installazione.- metti i tuoi test fuori dal tuo pacchetto Python. Questo lo rende difficile eseguire i test su un installato versione.
- crea un pacchetto che ha solo un
__init__.py
e quindi inserisci tutto il tuo codice in__init__.py
. Basta creare un modulo invece di un pacchetto, è più semplice.- prova a trovare degli hack magici per rendere Python in grado di importare il tuo modulo o pacchetto senza che l'utente abbia aggiunto la directory che lo contiene nella loro percorso di importazione (tramite
PYTHONPATH
o qualche altro meccanismo). Non lo farai gestire correttamente tutti i casi e gli utenti si arrabbierà con te quando il tuo il software non funziona nel loro ambiente.
Altri suggerimenti
Distutils supporta l'installazione di moduli, pacchetti e script . Se crei un setup.py
distutils che si riferisce a foo
come pacchetto e foo.py
come script, quindi foo. py
dovrebbe essere installato su / usr / local / bin
o qualunque sia il percorso di installazione dello script appropriato sul sistema operativo di destinazione e il pacchetto foo
dovrebbe essere installato su la directory site_packages
.
Dovresti chiamare l'eseguibile solo foo
, non foo.py
, quindi i tentativi di importare foo non lo useranno.
Per quanto riguarda la denominazione corretta: è difficile rispondere in astratto; avremmo bisogno di sapere cosa fa nello specifico. Ad esempio, se configura e controlla, chiamarlo -config o ctl potrebbe essere appropriato. Se si tratta di un'API shell per la libreria, dovrebbe avere lo stesso nome della libreria.
Il tuo modulo CLI è una cosa, il pacchetto che lo supporta è un'altra cosa. Non confondere i nomi con il modulo foo
(in un file foo.py
) e il pacchetto foo
(in una directory foo
con un file __init__.py
).
Hai due cose chiamate foo
: un modulo e un pacchetto. Cos'altro vuoi nominare foo
? Una classe? Una funzione? Una variabile?
Scegli un nome distintivo per il modulo foo o il pacchetto foo. foolib
, ad esempio, è un nome di pacchetto popolare.