Dieses Snippet stammt von einer früheren Antwort hier auf SO. Es ist ungefähr ein Jahr alt (und die Antwort wurde nicht akzeptiert). Ich bin neu in Python und ich finde den Systempfad einen echten Schmerz. Ich habe ein paar Funktionen in Skripten in verschiedenen Verzeichnissen geschrieben, und ich würde gerne in der Lage sein, sie in neue Projekte zu importieren, ohne durch Ringe springen zu müssen.
Dies ist das Snippet:
%Vor%Es ist von hier: Wie importieren Sie relative Importe in Python?
Ich hätte gerne ein Feedback, ob ich es benutzen kann oder nicht - und ob es unerwünschte Nebenwirkungen gibt, die einem Neuling vielleicht nicht auffallen.
Ich beabsichtige, es so zu verwenden:
%Vor%usw.
Ist es "sicher", die Funktion so zu nutzen, wie ich es beabsichtige?
Der "offizielle" und völlig sichere Ansatz ist das imp -Modul von die Standard-Python-Bibliothek.
Verwenden Sie imp.find_module , um das Modul auf Ihrer genau angegebenen Seite zu finden Liste der akzeptablen Verzeichnisse - es gibt ein 3-Tupel (file, pathname, description)
zurück - wenn nicht erfolgreich, ist file
tatsächlich None
(aber es kann auch ImportError
erhöhen, also solltest du ein try
/ except
dafür verwenden das ebenso wie if file is None:
) überprüfen.
Wenn die Suche erfolgreich ist, rufen Sie imp.load_module (in einer try
/ finally
, um sicherzustellen, dass Sie die Datei schließen!) mit den obigen drei Argumenten nach der ersten, die die gleiche name
sein müssen, die Sie an find_module
übergeben haben - es gibt das Modul-Objekt zurück (puh; - ).
Es fühlt sich an wie ein bisschen wie ein Hack, aber im Moment kann ich nicht an unbeabsichtigte Nebenwirkungen denken, die wahrscheinlich auftreten werden, zumindest nicht so lange, wie Sie es nur für Ihre eigenen Skripte verwenden . Im Grunde wird das übergeordnete Verzeichnis der angegebenen Datei (in Ihrem Beispiel /home/pydev/path1/
) vorübergehend zur Liste der Pfade hinzugefügt, die Python bei der Suche nach einem zu importierenden Modul überprüft.
Das einzige Risiko, das mir gerade einfällt, würde in einer Multithread-Umgebung auftreten, in der zwei oder mehr Threads (oder Prozesse) diese Funktion gleichzeitig ausführen. Wenn Thread A Modul A aus Pfad dirA/A.py
importieren möchte und Thread B Modul B aus Pfad dirB/B.py
importieren möchte, werden Sie für eine kurze Zeit mit dirA
und dirB
in sys.path
zusammengeführt . Und wenn es eine Datei namens B.py
in dirA
gibt, ist es möglich, dass Thread B ( dirA/B.py
) statt der gesuchten Datei ( dirB/B.py
) findet und somit das falsche Modul importiert. Aus diesem Grund würde ich es nicht in Produktionscode oder Code verwenden, den Sie an andere Leute verteilen werden (zumindest nicht, ohne sie zu warnen, dass dieser Hack hier ist!). In einer solchen Situation könnten Sie eine komplexere Funktion schreiben, mit der Sie die zu importierende Datei angeben können, ohne die Standardpfade zu stören. (Das ist zum Beispiel mod_python)
Ich wäre besorgt, dass Ihr Skriptname mit einem Modul übereinstimmen könnte, das früher im Pfad angezeigt wird. Um diese Angst zu zerstreuen, würde ich den Pfad vollständig durch eine neue Liste ersetzen, die nur das Verzeichnis enthält, das das Modul enthält, und es nach dem Import zurückstellen. Außerdem sollten Sie in eine Art Sperre einschließen , damit mehrere Threads, die versuchen, dasselbe zu tun, sich nicht gegenseitig stören.
Bitte beachten Sie, wie erwähnt, die Fadensicherheit. Ich bevorzuge etwas, das näher an einer Lösung ist, die in einem ähnlichen Beitrag gepostet wird. Die Hauptunterschiede unten: die Verwendung von Einfügen, um die Priorität des Imports anzugeben, die korrekte Wiederherstellung von sys.path mit try ... und schließlich das Festlegen des globalen Namespace.
%Vor%Tags und Links python