2010-09-01 20 views
15

En python puede hacer algo como esto para importar un módulo utilizando un nombre de archivo de cadena, y asignarle una espacio de nombre al espacio de nombres local.Python, importe una cadena de código Python como módulo

x = __import__(str) 

Me pregunto si hay una función relacionada que se llevará a tomar una cadena de código Python, en lugar de una ruta a un archivo con código Python, y devolver su espacio de nombres como una variable.

Por ejemplo,

str = "a = 5"; 
x = importstr(str) 
print x.a 
#output is 5 

Soy consciente de que podría escribir la cadena en un archivo, a continuación, utilizar __import__ en él, pero me gustaría saltar el archivo intermedio, si es posible.

La razón de esto es que estoy experimentando con la metaprogramación en python, y parece una buena solución para lo que estoy haciendo.

Respuesta

13

He aquí un example de crear dinámicamente objetos de módulo utilizando el imp module

+1

Sí, justo de la manera correcta. –

+0

hrm ... obtuve mi primer voto negativo con esta respuesta y no estoy seguro de por qué? –

+0

@JeremyBrown justo lo que estaba buscando. Como lo voté, considere el voto negativo deshecho;) –

2

¿Esto es algo que estás buscando?

my_namespace = {} 
exec "a = 5" in my_namespace 
print my_namespace["a"] 
+0

i preferiría no necesita hacer referencia a los elementos de espacio de nombres mediante una cadena de – Mike

5

Aquí es cómo importar una cadena como un módulo:

import sys,imp 

my_code = 'a = 5' 
mymodule = imp.new_module('mymodule') 
exec my_code in mymodule.__dict__  

por lo que ahora pueden acceder a los atributos del módulo (y funciones, clases, etc.) como:

mymodule.a 
>>> 5 

para ignorar cualquier nuevo intento de importar, agregar el módulo a sys:

sys.modules['mymodule'] = mymodule 
3

Por desgracia, el módulo imp fue recientemente en desuso (no tengo ni idea de por qué).

En su lugar, usted debe hacer esto:

from types import ModuleType 
import sys 

mod = ModuleType('my_module', 'doc string here') 
exec('a = 1', mod.__dict__) 
print(mod.a) # prints 1 
# add to sys.modules 
sys.modules['my_module'] = mod 

O puede utilizar PyExt 's RuntimeModule.from_string:

from pyext import RuntimeModule 

mod = RuntimeModule.from_string('a = 1') 
print(mod.a) # 1