Wie erhalte ich einen Verweis auf ein Modul im Modul selbst?

157

Wie kann ich innerhalb dieses Moduls einen Verweis auf ein Modul erhalten? Wie kann ich auch einen Verweis auf das Paket erhalten, das dieses Modul enthält?

Ram Rachum
quelle
7
Ich vermute , Sie könnten diese Frage stellen , weil Sie eine Variable in haben Modulumfang (zB BLAH = 10 außerhalb einer Funktion oder Klasse), dann eine Klasse / Funktion Variable namens BLAH, und Sie wollen , zu unterscheiden. Eine gültige Frage ist hier: Ist das notwendig? Scope-Regeln sind bekanntermaßen fehleranfällig, insbesondere von dem "Idioten", der Ihren Code nach Ihnen abholt (dh Sie, 6 Monate später). Tricks wie diese sind selten notwendig; Ich versuche, sie vollständig zu vermeiden, weil sie später so oft verwirrend und falsch modifiziert werden.
Kevin J. Rice
2
@ KevinJ.Rice "der 'Idiot', der Ihren Code nach Ihnen abholt (dh Sie, 6 Monate später)" machte meinen Tag!
Arctelix
8
Wen interessiert es, warum er die Frage stellt? Dafür gibt es viele triftige Gründe.
Christopher Barber
Muss geschlossen werden. Zu nützlich.
mlvljr

Antworten:

210
import sys
current_module = sys.modules[__name__]
Truppo
quelle
3
außer dass dies nicht ganz korrekt ist, wenn das Modul neu geladen wird; Ich glaube nicht, dass es einen Ort gibt, an dem eine Referenz garantiert aufbewahrt wird. Wenn dies der Fall wäre, würde das Nachladen nicht wirklich funktionieren, oder?
Dima Tisnek
14
Beim erneuten Laden wird dasselbe Modulobjekt erneut verwendet. Es wird kein neues Modulobjekt erstellt, daher ist es auch beim erneuten Laden korrekt.
Bukzor
18

Eine weitere Technik, die das sys-Modul nicht importiert und wohl - je nach Geschmack - einfacher ist:

current_module = __import__(__name__)

Beachten Sie, dass kein Import erfolgt. Python importiert jedes Modul nur einmal.

Uri
quelle
Dies scheint eine wirklich gute Möglichkeit zu sein, den Import von Sys zu vermeiden. Gibt es, abgesehen davon, dass das Lesen etwas kontraintuitiv ist, mögliche Nachteile für diesen Ansatz?
JeremyDouglass
@ JeremyDouglass. Nicht dass ich wüsste. Import ist eine legitime, dokumentierte, integrierte Funktion (die einzige xx- Funktion). Sie können es durch das 'importlib'-Paket ersetzen (Sie müssen es importieren). Vielleicht - mir ist das noch nie passiert - könnten Sie ein Problem mit dem relativen / absoluten Import haben, wenn ein Modul mit demselben Namen in sys.path verfügbar ist. In diesem Fall können Sie es mit dem Argument 'level' der Funktion lösen.
Uri
16

Wenn Sie eine Klasse in diesem Modul haben, ist die __module__Eigenschaft der Klasse der Modulname der Klasse. So können Sie über auf das Modul zugreifen sys.modules[klass.__module__]. Dies funktioniert auch für Funktionen.

Michael
quelle
4
Tatsächlich scheint die __module__Eigenschaft (zumindest) für eine Funktion kein Modul, sondern eine Zeichenfolge zu sein. also ein inspect.getabsfile(func.__module__)irgendwie „ Typeerror:‚o‘ist kein Modul, Klassen-, Methoden-, Funktion, Zurückverfolgungs, Rahmen oder Codeobjekt “; während inspect.getabsfile(sys.modules[o.__module__])scheint zu vergehen.
Sdaau
12

Sie können den Namen des aktuellen Moduls mit abrufen __name__

Die Modulreferenz finden Sie im sys.modulesWörterbuch.

Siehe die Python- Dokumentation

pkit
quelle
1

Sie können es von außen weitergeben:

mymod.init(mymod)

Nicht ideal, aber es funktioniert für meinen aktuellen Anwendungsfall.

Sam Watkins
quelle