Situation: - In meinem Projektordner befindet sich ein Modul namens "Kalender". - Ich möchte die integrierte Kalenderklasse aus den Python-Bibliotheken verwenden. - Wenn ich den Kalenderimportkalender verwende, beschwert es sich, weil versucht wird, von meinem Modul zu laden.
Ich habe einige Suchanfragen durchgeführt und kann anscheinend keine Lösung für mein Problem finden.
- Wie greife ich in Python auf ein Standardbibliotheksmodul zu, wenn ein lokales Modul mit demselben Namen vorhanden ist?
- http://docs.python.org/whatsnew/2.5.html
- Wie vermeide ich, beim Importieren eines Moduls in Python ständig den Namen des Moduls zu schreiben?
Irgendwelche Ideen, ohne mein Modul umbenennen zu müssen?
Antworten:
Die akzeptierte Lösung enthält einen inzwischen veralteten Ansatz.
Die importlib-Dokumentation hier gibt ein gutes Beispiel für die geeignetere Methode zum Laden eines Moduls direkt aus einem Dateipfad für Python> = 3.5:
Sie können also jede .py-Datei aus einem Pfad laden und den Modulnamen so einstellen, wie Sie möchten. Passen Sie also einfach den
module_name
benutzerdefinierten Namen an, den das Modul beim Importieren haben soll.Um ein Paket anstelle einer einzelnen Datei zu laden,
file_path
sollte der Pfad zum Stammverzeichnis des Pakets angegeben werden__init__.py
quelle
file_path=r"C:\Users\My User\My Path\Module File.py"
. Dann rief ichmodule_name
genau wie das veröffentlichte Modul an, so dass ich ein voll funktionsfähiges Skript hatte, das, entfernt von diesem Snippet, auf anderen PCs verwendet werden konnteDas Ändern des Namens Ihres Moduls ist nicht erforderlich. Sie können vielmehr absolute_import verwenden, um das Importverhalten zu ändern. Zum Beispiel importiere ich mit stem / socket.py das Socket-Modul wie folgt:
Dies funktioniert nur mit Python 2.5 und höher. Es aktiviert das Verhalten, das in Python 3.0 und höher standardmäßig verwendet wird. Pylint wird sich über den Code beschweren, aber er ist vollkommen gültig.
quelle
PYTHONPATH
. Eine andere Frage zeigt, wie man das löst.Eigentlich ist es ziemlich einfach, dies zu lösen, aber die Implementierung wird immer etwas fragil sein, da dies von den Interna des Python-Importmechanismus abhängt und sie in zukünftigen Versionen Änderungen unterliegen.
(Der folgende Code zeigt, wie sowohl lokale als auch nicht lokale Module geladen werden und wie sie nebeneinander existieren können.)
Die beste Lösung besteht nach Möglichkeit darin, zu vermeiden, dass Ihre Module mit demselben Namen wie die Standardbibliothek oder die integrierten Modulnamen benannt werden.
quelle
sys.modules
und nachfolgenden Versuchen, das lokale Modul zu laden, interagieren ?Die einzige Möglichkeit, dieses Problem zu lösen, besteht darin, die internen Importmaschinen selbst zu entführen. Das ist nicht einfach und voller Gefahren. Sie sollten das gralsförmige Leuchtfeuer um jeden Preis meiden, da die Gefahr zu gefährlich ist.
Benennen Sie stattdessen Ihr Modul um.
Wenn Sie lernen möchten, wie Sie die internen Importmaschinen entführen, erfahren Sie hier, wie Sie dies tun können:
Es gibt manchmal gute Gründe, in diese Gefahr zu geraten. Der Grund, den Sie angeben, ist nicht unter ihnen. Benennen Sie Ihr Modul um.
Wenn Sie den gefährlichen Pfad einschlagen, wird ein Problem darin bestehen, dass beim Laden eines Moduls ein 'offizieller Name' angezeigt wird, sodass Python vermeiden kann, den Inhalt dieses Moduls jemals wieder analysieren zu müssen. Eine Zuordnung des 'offiziellen Namens' eines Moduls zum Modulobjekt selbst finden Sie in
sys.modules
.Dies bedeutet, dass, wenn Sie sich
import calendar
an einem Ort befinden, jedes importierte Modul als das Modul mit dem offiziellen Namen betrachtet wirdcalendar
und alle anderen Versuche,import calendar
irgendwo anders, einschließlich in anderem Code, der Teil der Python-Hauptbibliothek ist, diesen Kalender erhalten.Es ist möglicherweise möglich, einen Kundenimporter mithilfe des imputil-Moduls in Python 2.x zu entwerfen, das dazu führte , dass Module, die aus bestimmten Pfaden geladen wurden, die von ihnen importierten Module in etwas anderem als dem
sys.modules
ersten oder ähnlichem nachschlagen . Aber das ist eine extrem haarige Sache, und es wird in Python 3.x sowieso nicht funktionieren.Es gibt eine extrem hässliche und schreckliche Sache, die Sie tun können, ohne den Importmechanismus anzuschließen. Dies ist etwas, was Sie wahrscheinlich nicht tun sollten, aber es wird wahrscheinlich funktionieren. Es verwandelt Ihr
calendar
Modul in eine Mischung aus dem Systemkalendermodul und Ihrem Kalendermodul. Vielen Dank an Boaz Yaniv für das Skelett der Funktion, die ich benutze . Fügen Sie dies am Anfang Ihrercalendar.py
Datei ein:quelle
code
) auf, was bedeutet, dass nur ein Bruchteil der Entwickler jemals Probleme mit diesem "Zusammenführungs-Hack" haben könnte. Benutzer wären überhaupt nicht betroffen.Ich möchte meine Version anbieten, die eine Kombination aus der Lösung von Boaz Yaniv und Omnifarious ist. Es wird die Systemversion eines Moduls importiert, mit zwei Hauptunterschieden zu den vorherigen Antworten:
Stellen Sie dies an einen zugänglichen Ort, damit Sie es aufrufen können (ich habe meine in meiner __init__.py-Datei):
Beispiel
Ich wollte mysql.connection importieren, hatte aber bereits ein lokales Paket namens mysql (die offiziellen mysql-Dienstprogramme). Um den Connector aus dem System-MySQL-Paket zu erhalten, habe ich Folgendes ersetzt:
Mit diesem:
Ergebnis
quelle
Ändern Sie den Importpfad:
quelle
sys.modules
und kein Modul mit demselben Namen erneut importiert.