2010-02-22 16 views
12

Dado que tengo el objeto de código para un módulo, ¿cómo obtengo el objeto de módulo correspondiente?Cómo generar un objeto de módulo desde un objeto de código en Python

Parece que moduleNames = {}; exec code in moduleNames hace algo muy parecido a lo que quiero. Devuelve los valores globales declarados en el módulo a un diccionario. Pero si quiero el objeto del módulo real, ¿cómo lo obtengo?

EDITAR: Parece que puede hacer rodar su propio objeto de módulo. El tipo de módulo no está muy bien documentada, pero se puede hacer algo como esto:

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

El acceso preferente punto para el tipo de módulo es 'types.ModuleType'. –

Respuesta

19

Como comentario ya indica, en Python de hoy la forma preferida para crear instancias de tipos que no tienen una función de nombres consiste en llamar a la clase obtenida a través del módulo types de la librería estándar:

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

en cuenta que esto no insertar automáticamente el nuevo módulo en sys.modules:

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

Esa es una tarea que debe realizar a mano:

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

Esto puede ser importante, ya objeto de código de un módulo normalmente se ejecuta después de agregado a sys.modules el módulo - por ejemplo, es perfectamente correcto para tales código para hacer referencia a sys.modules[__name__], y que fallaría (KeyError) si olvidó este paso. Después de este paso, y el establecimiento de m.__file__ como que ya tiene en su edición,

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

(o el equivalente en Python 3 exec es una función, si Python 3 es lo que estás usando, por supuesto, -) es correcto (por supuesto, normalmente habrá obtenido el objeto de código por medios más sutiles que compilar una cadena, pero eso no es importante para su pregunta ;-).

En las versiones anteriores de Python que habría utilizado el módulo en lugar del módulo typesnew para hacer un nuevo objeto de módulo en el inicio, pero new está obsoleta desde Python 2.6 y se retira en Python 3.

Cuestiones relacionadas