Wenn ich CreateUser.py
in das Hauptverzeichnis user_management wechsle, kann ich einfach Folgendes verwenden: import Modules.LDAPManager
zum Importieren LDAPManager.py
--- das funktioniert.
Bitte nicht . Auf diese Weise das LDAPManager
verwendete Modul CreateUser
wird nicht die gleiche wie die über andere Importe importiert werden. Dies kann zu Problemen führen, wenn sich im Modul ein globaler Status befindet oder wenn das Beizen / Entpicken erfolgt. Vermeiden Sie Importe, die nur funktionieren, weil sich das Modul zufällig im selben Verzeichnis befindet.
Wenn Sie eine Paketstruktur haben, sollten Sie entweder:
Verwenden Sie relative Importe, dh wenn das in CreateUser.py
ist Scripts/
:
from ..Modules import LDAPManager
Beachten Sie, dass dies von PEP 8 nur deshalb empfohlen wurde (beachten Sie die Vergangenheitsform ), weil alte Versionen von Python sie nicht sehr gut unterstützten, aber dieses Problem wurde vor Jahren gelöst. Die aktuelle Version von PEP 8 schlägt sie als akzeptable Alternative zu absoluten Importen vor. Ich mag sie tatsächlich in Paketen.
Verwenden Sie absolute Importe mit dem gesamten Paketnamen ( CreateUser.py
in Scripts/
):
from user_management.Modules import LDAPManager
Damit der zweite funktioniert, user_management
sollte das Paket im installiert werden PYTHONPATH
. Während der Entwicklung können Sie die IDE so konfigurieren, dass dies geschieht, ohne dass Sie sys.path.append
irgendwo manuell Anrufe hinzufügen müssen .
Auch finde ich es seltsam, dass Scripts/
es sich um ein Unterpaket handelt. Denn in einer realen Installation würde das user_management
Modul unter dem site-packages
im lib/
Verzeichnis gefundenen Verzeichnis installiert (welches Verzeichnis auch immer zum Installieren von Bibliotheken in Ihrem Betriebssystem verwendet wird), während die Skripte unter einem bin/
Verzeichnis installiert werden sollten (welches auch immer ausführbare Dateien für Ihr Betriebssystem enthält).
Tatsächlich glaube ich, dass Script/
es nicht einmal unter sein sollte user_management
. Es sollte auf dem gleichen Niveau sein user_management
. Auf diese Weise müssen Sie nicht verwenden -m
, sondern müssen nur sicherstellen, dass das Paket gefunden werden kann (dies ist wiederum eine Frage der Konfiguration der IDE, der korrekten Installation des Pakets oder der Verwendung PYTHONPATH=. python Scripts/CreateUser.py
zum Starten der Skripte mit dem richtigen Pfad).
Zusammenfassend würde ich folgende Hierarchie verwenden:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
Dann sollte der Code von CreateUser.py
und FindUser.py
absolute Importe verwenden, um die Module zu importieren:
from user_management.Modules import LDAPManager
Während der Installation stellen Sie sicher, dass user_management
irgendwo in den PYTHONPATH
Skripten im Verzeichnis für ausführbare Dateien landet, damit diese die Module finden können. Während der Entwicklung verlassen Sie sich entweder auf die IDE-Konfiguration oder Sie starten das CreateUser.py
Hinzufügen des Scripts/
übergeordneten Verzeichnisses zum PYTHONPATH
(ich meine das Verzeichnis, das beide user_management
und enthält Scripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
Oder Sie können das PYTHONPATH
global ändern, sodass Sie dies nicht jedes Mal angeben müssen. Unter Unix-Betriebssystemen (Linux, Mac OS X usw.) können Sie eines der Shell-Skripte ändern, um die PYTHONPATH
externe Variable zu definieren. Unter Windows müssen Sie die Einstellungen für Umgebungsvariablen ändern.
Nachtrag Ich glaube, wenn Sie Python2 verwenden, ist es besser, implizite relative Importe zu vermeiden, indem Sie Folgendes eingeben:
from __future__ import absolute_import
oben in Ihren Modulen. Auf diese Weise bedeutet import X
immer , das Toplevel- Modul zu importieren, X
und es wird niemals versucht, die X.py
Datei zu importieren , die sich im selben Verzeichnis befindet (wenn sich dieses Verzeichnis nicht im Verzeichnis befindet PYTHONPATH
). Auf diese Weise besteht die einzige Möglichkeit, einen relativen Import durchzuführen, darin, die explizite Syntax (the from . import X
) zu verwenden, die besser ist ( explizit ist besser als implizit ).
Dies stellt sicher, dass Sie niemals die "falschen" impliziten relativen Importe verwenden, da diese ein ImportError
klares Signal dafür auslösen würden, dass etwas nicht stimmt. Andernfalls könnten Sie ein Modul verwenden, das Ihrer Meinung nach nicht so ist.
python -m user_management.Scripts.CreateUser