2010-02-22 6 views
12

Gegeben, dass ich das Codeobjekt für ein Modul habe, wie bekomme ich das entsprechende Modulobjekt?Wie man ein Modulobjekt aus einem Codeobjekt in Python generiert

Es sieht aus wie moduleNames = {}; exec code in moduleNames tut etwas sehr nah an dem, was ich will. Sie gibt die im Modul deklarierten Globals in ein Dictionary zurück. Aber wenn ich das eigentliche Modulobjekt haben möchte, wie bekomme ich es?

EDIT: Es sieht aus wie Sie Ihr eigenes Modulobjekt rollen können. Der Modultyp ist nicht bequem dokumentiert, aber man kann so etwas tun:

import sys 
module = sys.__class__ 
del sys 
foo = module('foo', 'Doc string') 
foo.__file__ = 'foo.pyc' 
exec code in foo.__dict__ 
+0

Der bevorzugte Zugang Punkt für den Modultyp ist 'types.ModuleType'. –

Antwort

19

als Kommentar zeigt bereits, in der heutigen Python die bevorzugte Art und Weise Typen zu instanziiert, die zu tun haben, nicht eingebaute Namen sind rufen Sie die über das types Modul erhalten Typ aus der Standardbibliothek:

>>> import types 
>>> m = types.ModuleType('m', 'The m module') 

beachten Sie, dass dies tut nicht automatisch das neue Modul in sys.modules einfügen:

>>> import sys 
>>> sys.modules['m'] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 'm' 

Das ist eine Aufgabe, die Sie von Hand durchführen müssen:

>>> sys.modules['m'] = m 
>>> sys.modules['m'] 
<module 'm' (built-in)> 

Dies kann wichtig sein, da ein Codeobjekt des Moduls normalerweise nach führt das das Modul hinzugefügt sys.modules - zum Beispiel für einen solchen vollkommen richtig ist Code, um sich auf sys.modules[__name__] zu beziehen, und das würde fehlschlagen (KeyError), wenn Sie diesen Schritt vergessen haben. Nach dieser Schritt und Einstellung m.__file__ wie Sie bereits in Ihrem bearbeiten haben,

>>> code = compile("a=23", "m.py", "exec") 
>>> exec code in m.__dict__ 
>>> m.a 
23 

(oder den Python 3 äquivalent, wo exec eine Funktion ist, wenn Python 3 ist das, was Sie verwenden, natürlich, -) ist korrekt (natürlich haben Sie das Code-Objekt normalerweise subtiler erhalten, als einen String zu kompilieren, aber das ist für Ihre Frage nicht wesentlich ;-).

In älteren Versionen von Python Sie das new Modul verwendet haben würde anstelle des types Modul ein neues Modul-Objekt am Anfang zu machen, aber new ist seit Python veraltet 2.6 und entfernt in Python 3.