Se eu mover CreateUser.py
para o diretório principal user_management, posso facilmente usar: import Modules.LDAPManager
para importar LDAPManager.py
--- isso funciona.
Por favor, não . Desta forma, o LDAPManager
módulo usado por CreateUser
irá não ser o mesmo que o importado via outras importações. Isso pode criar problemas quando você tem algum estado global no módulo ou durante a decapagem / retirada da colheita. Evite importações que funcionam apenas porque o módulo está no mesmo diretório.
Quando você tem uma estrutura de pacote, você deve:
Use importações relativas, ou seja, se CreateUser.py
estiver em Scripts/
:
from ..Modules import LDAPManager
Note-se que este era (note o passado tensa) desencorajado pelo PEP 8 só porque versões antigas do python não apoiá-los muito bem, mas este problema foi resolvido anos atrás. A atual versão do PEP 8 não sugeri-los como uma alternativa aceitável para as importações absolutos. Na verdade, gosto deles dentro de pacotes.
Use importações absolutas usando o nome completo do pacote ( CreateUser.py
in Scripts/
):
from user_management.Modules import LDAPManager
Para que o segundo funcione, o pacote user_management
deve ser instalado dentro do PYTHONPATH
. Durante o desenvolvimento, você pode configurar o IDE para que isso aconteça, sem ter que adicionar chamadas manualmente para sys.path.append
qualquer lugar.
Também acho estranho que Scripts/
seja um subpacote. Porque em uma instalação real, o user_management
módulo seria instalado sob o site-packages
encontrado no lib/
diretório (qualquer diretório é usado para instalar bibliotecas em seu sistema operacional), enquanto os scripts devem ser instalados em um bin/
diretório (o que contiver executáveis para seu sistema operacional).
Na verdade, acredito Script/
que nem deveria estar abaixo user_management
. Deve estar no mesmo nível de user_management
. Desta forma, você não precisa usar -m
, mas simplesmente certificar-se de que o pacote pode ser encontrado (novamente, é uma questão de configurar o IDE, instalar o pacote corretamente ou usar PYTHONPATH=. python Scripts/CreateUser.py
para iniciar os scripts com o caminho correto).
Em resumo, a hierarquia que eu usaria é:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
Em seguida, o código de CreateUser.py
e FindUser.py
deve usar importações absolutas para importar os módulos:
from user_management.Modules import LDAPManager
Durante a instalação, certifique-se de que user_management
termina em algum lugar no PYTHONPATH
e os scripts dentro do diretório para executáveis, de modo que eles possam localizar os módulos. Durante o desenvolvimento, você depende da configuração do IDE ou inicia CreateUser.py
adicionando o Scripts/
diretório pai ao PYTHONPATH
(quero dizer, o diretório que contém tanto user_management
e Scripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
Ou você pode modificar o PYTHONPATH
globalmente para que não precise especificar isso todas as vezes. Em sistemas operacionais Unix (Linux, Mac OS X etc.), você pode modificar um dos scripts de shell para definir a PYTHONPATH
variável externa, no Windows você deve alterar as configurações das variáveis ambientais.
Adendo , acredito, se você estiver usando python2, é melhor evitar as importações relativas implícitas, colocando:
from __future__ import absolute_import
na parte superior de seus módulos. Desta forma import X
sempre significa para importar o nível superior do módulo X
e nunca vai tentar importar o X.py
arquivo que está no mesmo diretório (se esse diretório não está no PYTHONPATH
). Dessa forma, a única maneira de fazer uma importação relativa é usar a sintaxe explícita (o from . import X
), que é melhor ( explícita é melhor do que implícita ).
Isso garantirá que você nunca use as importações relativas implícitas "falsas", uma vez que elas gerariam uma ImportError
sinalização clara de que algo está errado. Caso contrário, você pode usar um módulo que não seja o que você pensa que é.
python -m user_management.Scripts.CreateUser
Do Python 2.5 em diante, você pode usar
from ..Modules import LDAPManager
O período inicial leva você "para cima" um nível em sua hierarquia.
Consulte a documentação do Python sobre referências dentro do pacote para importações.
fonte
Na "raiz"
__init__.py
você também pode fazer umimport sys sys.path.insert(1, '.')
que deve tornar ambos os módulos importáveis.
fonte