Si je passe CreateUser.py
au répertoire principal user_management, je peux facilement utiliser: import Modules.LDAPManager
pour importer LDAPManager.py
--- cela fonctionne.
S'il vous plaît, ne le faites pas . De cette façon, le LDAPManager
module utilisé par neCreateUser
sera pas le même que celui importé via d'autres importations. Cela peut créer des problèmes lorsque vous avez un état global dans le module ou pendant le décapage / décapage. Éviter importations qui fonctionnent uniquement parce que le module se trouve dans le même répertoire.
Lorsque vous avez une structure de package, vous devez soit:
Utilisez les importations relatives, c'est-à-dire si le CreateUser.py
est dans Scripts/
:
from ..Modules import LDAPManager
Notez que c'était (notez le passé ) découragé par PEP 8 uniquement parce que les anciennes versions de python ne les supportaient pas très bien, mais ce problème a été résolu il y a des années. Le courant version du PEP 8 ne les suggère comme une alternative acceptable aux importations en termes absolus. Je les aime vraiment à l' intérieur des paquets.
Utilisez les importations absolues en utilisant le nom complet du package ( CreateUser.py
in Scripts/
):
from user_management.Modules import LDAPManager
Pour que le second fonctionne, le package user_management
doit être installé dans le PYTHONPATH
. Pendant le développement, vous pouvez configurer l'EDI pour que cela se produise, sans avoir à ajouter manuellement des appels àsys.path.append
n'importe où.
Je trouve aussi étrange que ce Scripts/
soit un sous-paquet. Parce que dans une installation réelle, le user_management
module serait installé sous le répertoire site-packages
trouvé dans le lib/
répertoire (quel que soit le répertoire utilisé pour installer les bibliothèques dans votre système d'exploitation), tandis que les scripts devraient être installés sous unbin/
répertoire (celui qui contient les exécutables pour votre système d'exploitation).
En fait, je pense Script/
qu'il ne devrait même pas être en dessous user_management
. Il devrait être au même niveau de user_management
. De cette façon, vous n'avez pas à utiliser -m
, mais vous devez simplement vous assurer que le package peut être trouvé (il s'agit encore une fois de configurer l'EDI, d'installer correctement le package ou d'utiliser PYTHONPATH=. python Scripts/CreateUser.py
pour lancer les scripts avec le chemin correct).
En résumé, la hiérarchie que j'utiliserais est:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
Puis le code de CreateUser.py
et FindUser.py
doit utiliser des importations absolues pour importer les modules:
from user_management.Modules import LDAPManager
Pendant l'installation, assurez-vous que cela user_management
se termine quelque part dans le PYTHONPATH
, et les scripts à l'intérieur du répertoire pour les exécutables afin qu'ils puissent trouver les modules. Pendant le développement, vous comptez soit sur la configuration IDE, soit vous lancez l' CreateUser.py
ajout du Scripts/
répertoire parent au PYTHONPATH
(je veux dire le répertoire qui contient les deuxuser_management
et Scripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
Ou vous pouvez modifier le PYTHONPATH
globalement afin de ne pas avoir à le spécifier à chaque fois. Sur les OS Unix (Linux, Mac OS X etc.), vous pouvez modifier l'un des scripts shell pour définir la PYTHONPATH
variable externe, sous Windows, vous devez changer les paramètres des variables d'environnement.
Addenda Je pense que si vous utilisez python2, il vaut mieux éviter les importations relatives implicites en mettant:
from __future__ import absolute_import
en haut de vos modules. De cette manière signifie import X
toujours importer le module de niveau supérieurX
et n'essaiera jamais d'importer le X.py
fichier qui se trouve dans le même répertoire (si ce répertoire n'est pas dans le PYTHONPATH
). De cette façon, la seule façon de faire une importation relative est d'utiliser la syntaxe explicite (la from . import X
), qui est meilleure ( explicite vaut mieux qu'implicite ).
Cela garantira que vous n'utiliserez jamais les importations relatives implicites "fausses", car celles-ci soulèveraient un ImportError
signalement clair que quelque chose ne va pas. Sinon, vous pourriez utiliser un module qui n'est pas ce que vous pensez.
python -m user_management.Scripts.CreateUser
À partir de Python 2.5, vous pouvez utiliser
from ..Modules import LDAPManager
La période principale vous fait «monter» d'un niveau dans votre héritage.
Consultez la documentation Python sur les références intra-package pour les importations.
la source
Dans la "racine",
__init__.py
vous pouvez également faire unimport sys sys.path.insert(1, '.')
ce qui devrait rendre les deux modules importables.
la source