2010-02-22 6 views
12

Étant donné que j'ai l'objet code pour un module, comment puis-je obtenir l'objet module correspondant?Comment générer un objet module à partir d'un objet code en Python

On dirait que moduleNames = {}; exec code in moduleNames fait quelque chose de très proche de ce que je veux. Il renvoie les globales déclarées dans le module dans un dictionnaire. Mais si je veux l'objet module réel, comment l'obtenir?

EDIT: Il semble que vous pouvez rouler votre propre objet de module. Le type de module n'est pas convenablement documenté, mais vous pouvez faire quelque chose comme ceci:

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

L'accès privilégié point pour le type de module est 'types.ModuleType'. –

Répondre

19

Comme un commentaire indique déjà, en Python aujourd'hui le moyen privilégié pour instancier types qui n'ont un nom intégré est à appeler le type obtenu via le module types de la bibliothèque standard:

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

Notez que cela ne pas insère automatiquement le nouveau module dans sys.modules:

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

C'est une tâche que vous devez effectuer manuellement:

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

Cela peut être important, car un de code objet du module exécute normalement après de module ajouté à sys.modules - par exemple, il est tout à fait correct pour un tel code pour se référer à sys.modules[__name__], et cela échouerait (KeyError) si vous avez oublié cette étape. Après cette étape, et la mise en m.__file__ que vous avez déjà dans votre édition,

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

(ou l'équivalent Python 3 où exec est une fonction, si Python 3 est ce que vous utilisez, bien sûr; -) est correct (bien sûr, vous aurez normalement obtenu l'objet code par des moyens plus subtils que la compilation d'une chaîne, mais ce n'est pas important pour votre question ;-).

vous dans les anciennes versions de Python ont utilisé le module new au lieu du module types pour faire un nouvel objet de module au début, mais new est obsolète depuis Python 2.6 et retiré en Python 3.