En Python, ¿por qué no funciona una importación en un exec en una función?

Puedo poner una statement de importación en una cadena, ejecutarlo y funciona (imprime un dígito aleatorio):

code = """ import random def f(): print random.randint(0,9) """ def f(): pass exec code f() 

Ahora, si pongo el exec code y f() en su propia función y lo llamo, no funciona.

 def test(): exec code f() test() 

Dice NameError: global name 'random' is not defined . ¿Tienes idea de lo que está pasando? Gracias

Qué tal esto:

 def test(): exec (code, globals()) f() 

Lo que sucede aquí es que el módulo aleatorio se está importando como una variable local en la prueba. Prueba esto

 def test(): exec code print globals() print locals() f() 

imprimirá

 {'code': '\nimport random\ndef f():\n print random.randint(0,9)\n', '__builtins__': , '__package__': None, 'test': , '__name__': '__main__', '__doc__': None} {'random': , 'f': } 

La razón por la que no puedo ver al random es que f no es una función anidada dentro de la test si hiciste esto:

 def test(): import random def f(): print random.randint(0,9) f() 

funcionaria Sin embargo, las funciones anidadas requieren que la función externa contenga la definición de la función interna cuando se comstack la función externa; esto se debe a que es necesario configurar las variables de celda para que contengan las variables que se comparten entre las dos funciones (externa e interna).

Para entrar aleatoriamente en el espacio de nombres global, solo harías algo como esto

 exec code in globals(),globals() 

Los argumentos para ejecutar después de la palabra clave in son los espacios de nombres globales y locales en los que se ejecuta el código (y, por lo tanto, donde se almacenan los nombres definidos en el código ejecutable).

Especifique que desea el módulo random global

 code = """ import random def f(): global random print random.randint(0,9) """ 

El problema aquí es que está importando el módulo random a su scope de función, no el scope global.