2012-09-20 29 views
21

puedo poner una declaración de importación en una cadena, exec, y funciona (imprime un dígito al azar):En Python, ¿por qué no funciona una importación en un ejecutivo en una función?

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

def f(): 
    pass 

exec code 
f() 

Ahora, si pongo exec code y f() en su propia función y llamarla, que doesn no funciona

def test(): 
    exec code 
    f() 

test() 

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

+0

Por curiosidad, ¿por qué querrías hacer esto? –

+1

Este es un signo de mal diseño - evitar. –

+0

+ Vincent Savard, trabajo con un producto basado en Java que me permite escribir scripts de Python en él, y puedo configurar mi script para que se ejecute cuando ocurren ciertos eventos predefinidos. Sin embargo, no puedo usar la declaración de importación estándar para cargar otra de mis secuencias de comandos si deseo usar sus funciones como una biblioteca. En su lugar, debo cargar el código de ese otro script de la base de datos y ejecutarlo(). Y el problema es que ese otro script importa bibliotecas de Java que yo no tenía, en cuyo caso llamar a una función de biblioteca causa el problema descrito por + Alex Varga – Preacher

Respuesta

12

¿Qué tal esto:

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

especificar que desea que el módulo global random

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

El problema aquí es que va a importar el módulo random en su ámbito de función, no el ámbito global.

14

¿Qué está pasando aquí es que el módulo random se importa como una variable local en la prueba. Pruebe esta

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

imprimirá

{'code': '\nimport random\ndef f():\n print random.randint(0,9)\n', '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x02958BF0>, '__name__': '__main__', '__doc__': None} 
{'random': <module 'random' from 'C:\Python27\lib\random.pyc'>, 'f': <function f at 0x0295A070>} 

La razón f no pueden ver random es que f no es una función anidada dentro de test --Si le hizo esto:

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

funcionaría. Sin embargo, las funciones anidadas requieren que la función externa contenga la definición de la función interna cuando se compila la función externa; esto se debe a que necesita configurar variables de celda para contener variables que se comparten entre las dos funciones (externa e interna).

Para llegar al azar en el espacio de nombres global, usted acaba de hacer algo como esto

exec code in globals(),globals() 

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

Cuestiones relacionadas