Wenn ich CreateUser.pyin das Hauptverzeichnis user_management wechsle, kann ich einfach Folgendes verwenden: import Modules.LDAPManagerzum Importieren LDAPManager.py
--- das funktioniert.
Bitte nicht . Auf diese Weise das LDAPManagerverwendete Modul CreateUserwird 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.pyist 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.pyin Scripts/):
from user_management.Modules import LDAPManager
Damit der zweite funktioniert, user_managementsollte 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.appendirgendwo 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_managementModul unter dem site-packagesim 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.pyzum 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.pyund FindUser.pyabsolute Importe verwenden, um die Module zu importieren:
from user_management.Modules import LDAPManager
Während der Installation stellen Sie sicher, dass user_managementirgendwo in den PYTHONPATHSkripten 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.pyHinzufügen des Scripts/übergeordneten Verzeichnisses zum PYTHONPATH(ich meine das Verzeichnis, das beide user_managementund enthält Scripts):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
Oder Sie können das PYTHONPATHglobal ä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 PYTHONPATHexterne 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, Xund es wird niemals versucht, die X.pyDatei 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 ImportErrorklares 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