Se mi sposto CreateUser.py
nella directory principale user_management, posso facilmente usare: import Modules.LDAPManager
to import LDAPManager.py
--- funziona.
Per favore, non farlo . In questo modo il LDAPManager
modulo utilizzato da CreateUser
sarà non essere uguale a quello importato tramite altre importazioni. Ciò può creare problemi quando si dispone di uno stato globale nel modulo o durante il decapaggio / rimozione. Evitare importazioni che funzionano solo perché il modulo si trova nella stessa directory.
Quando hai una struttura del pacchetto dovresti:
Usa le importazioni relative, ovvero se CreateUser.py
è in Scripts/
:
from ..Modules import LDAPManager
Si noti che questo è stato (notare il passato ) scoraggiato da PEP 8 solo perché le vecchie versioni di python non le supportavano molto bene, ma questo problema è stato risolto anni fa. La corrente versione di PEP 8 non li suggerisce come alternativa accettabile importazioni assoluti. In realtà mi piacciono all'interno dei pacchetti.
Usa importazioni assolute utilizzando l'intero nome del pacchetto ( CreateUser.py
in Scripts/
):
from user_management.Modules import LDAPManager
Affinché il secondo funzioni il pacchetto user_management
deve essere installato all'interno di PYTHONPATH
. Durante lo sviluppo è possibile configurare l'IDE in modo che ciò avvenga, senza dover aggiungere manualmente chiamate sys.path.append
ovunque.
Inoltre trovo strano che Scripts/
sia un sottopacchetto. Perché in un'installazione reale il user_management
modulo verrebbe installato sotto il site-packages
trovato nella lib/
directory (qualunque directory viene utilizzata per installare le librerie nel tuo sistema operativo), mentre gli script dovrebbero essere installati in una bin/
directory (a seconda di quale contiene eseguibili per il tuo sistema operativo).
In effetti credo Script/
che non dovrebbe nemmeno essere sotto user_management
. Dovrebbe essere allo stesso livello di user_management
. In questo modo non non è necessario utilizzare -m
, ma si deve semplicemente assicurarsi che il pacchetto può essere trovato (questo è ancora una volta una questione di configurare l'IDE, l'installazione del pacchetto correttamente o usando PYTHONPATH=. python Scripts/CreateUser.py
per lanciare gli script con il percorso corretto).
In sintesi, la gerarchia che userei è:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
Quindi il codice di CreateUser.py
e FindUser.py
dovrebbe utilizzare importazioni assolute per importare i moduli:
from user_management.Modules import LDAPManager
Durante l'installazione assicurati che user_management
finisca da qualche parte in PYTHONPATH
, e gli script all'interno della directory per gli eseguibili in modo che siano in grado di trovare i moduli. Durante lo sviluppo ti affidi alla configurazione IDE o lanci CreateUser.py
aggiungendo la Scripts/
directory padre a PYTHONPATH
(intendo la directory che contiene sia user_management
e Scripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
Oppure puoi modificare PYTHONPATH
globalmente in modo da non doverlo specificare ogni volta. Su sistemi operativi unix (linux, Mac OS X ecc.) Puoi modificare uno degli script della shell per definire la PYTHONPATH
variabile esterna, su Windows devi modificare le impostazioni delle variabili ambientali.
Addendum Credo, se stai usando python2, è meglio assicurarti di evitare importazioni relative implicite inserendo:
from __future__ import absolute_import
nella parte superiore dei tuoi moduli. In questo modo import X
sempre significa importare il toplevel modulo X
e non sarà mai provare a importare il X.py
file è nella stessa directory (se tale directory non è nel PYTHONPATH
). In questo modo l' unico modo per eseguire un'importazione relativa è utilizzare la sintassi esplicita (the from . import X
), che è migliore ( esplicito è meglio dell'implicito ).
In questo modo non ti capiterà mai di utilizzare le importazioni relative implicite "fasulle", poiché queste genererebbero un ImportError
chiaro segnale che qualcosa non va. Altrimenti potresti usare un modulo che non è quello che pensi che sia.
python -m user_management.Scripts.CreateUser