2009-11-04 3 views
111

Wie kann ich einen Bezug zu einem Modul innerhalb dieses Moduls erhalten? Wie kann ich einen Verweis auf das Paket erhalten, das dieses Modul enthält?Python: Wie bekomme ich einen Verweis auf ein Modul im Modul selbst?

+5

Ich vermute, Sie könnten diese Frage stellen, weil Sie eine Variable in ** Modul Umfang ** (zB BLAH = 10 außerhalb einer Funktion oder Klasse), dann eine ** Klasse/Funktion Variable ** namens BLAH und du willst unterscheiden. Eine gültige Frage hier ist: ** Ist das notwendig? ** Scope-Regeln sind notorisch anfällig für Fehler, vor allem durch die "Idiot", die Ihren Code nach Ihnen abholt (d. H. Sie, 6 Monate später). Tricks wie diese sind selten notwendig; Ich versuche, sie komplett zu vermeiden, weil sie später oft verwirrend und falsch modifiziert werden. –

+1

@ KevinJ.Rice "der 'Idiot', der Ihren Code nach Ihnen abholt (d. H. Sie, 6 Monate später)" machte meinen Tag! – arctelix

+4

Wen kümmert es, warum er die Frage stellt? Es gibt viele gute Gründe, dies zu tun. –

Antwort

165
import sys 
current_module = sys.modules[__name__] 
+3

außer dies wird nicht richtig sein, wenn das Modul neu geladen wird; Ich glaube nicht, dass es einen Ort gibt, an dem eine Referenz garantiert ist. Wenn das der Fall wäre, würde das Nachladen nicht wirklich funktionieren, oder? –

+10

Reloading verwendet dasselbe Modulobjekt erneut; Es wird kein neues Modulobjekt erstellt, daher ist es immer noch korrekt, wenn es neu geladen wird. – bukzor

14

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

+4

Eigentlich scheint es (zumindest) für eine Funktion, die '__module__' Eigenschaft ist kein Modul, sondern eine Zeichenfolge; daher schlägt eine 'inspect.getabsfile (func .__ modul __)' mit "_TypeError: 'os' ist kein Modul, Klasse, Methode, Funktion, Traceback, Frame oder Code Objekt_"; während 'inspect.getabsfile (sys.modules [o .__ modul __])' scheint zu bestehen. – sdaau

+0

Danke, repariert es. – Michael

8

Sie können den Namen des aktuellen Moduls erhalten __name__

Das Modul Referenz verwendet, kann im sys.modules Wörterbuch zu finden.

Siehe den Python documentation

+3

Ich schätze den Doc-Link. –

3

Eine weitere Technik, die nicht das sys-Modul nicht importiert werden, und wohl - nach Geschmack hängt - einfacher:

current_module = __import__(__name__) 

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

+0

Dies scheint eine wirklich nette Möglichkeit zu sein, sys zu vermeiden. Abgesehen davon, dass das Lesen etwas kontraintuitiv ist, gibt es mögliche Nachteile bei diesem Ansatz? – JeremyDouglass

+0

@ JeremyDouglass. Nicht dass ich wüsste. __import__ ist eine legitime, dokumentierte, eingebaute Funktion (die einzige Funktion __xx__). Sie können es durch das 'importlib' Paket ersetzen (Sie müssen es importieren). Vielleicht - mir ist das nie passiert - könnten Sie ein Problem mit dem relativen/absoluten Import haben, wenn ein Modul mit dem gleichen Namen in sys.path verfügbar ist. In diesem Fall können Sie es mit dem Argument 'level' der Funktion lösen. – Uri

1

Sie können es von außen passieren in:

mymod.init(mymod) 

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

Verwandte Themen