Quiero ejecutar un código Python, escrito en tiempo de ejecución, así que obtengo la cadena y llamo

ejecutivo (pp, globales (), locales ())

Donde pp es la cadena. Funciona bien, excepto para llamadas recursivas, e. g., por ejemplo, este código está bien:

def horse():
    robot.step()
    robot.step()
    robot.turn(-1)
    robot.step()

while True:
    horse()

Pero este no es:

def horse():
    robot.step()
    robot.step()
    robot.turn(-1)
    robot.step()
    horse()

horse()

NameError: el nombre global 'caballo' no está definido

¿Hay alguna manera de ejecutar código recursivo también?

Actualizar

a = """\
def rec(n):
    if n > 10:
        return
    print n
    return rec(n+1)

rec(5)"""

exec(a)

Funciona si se coloca en el nivel superior. Pero si se mueve dentro de una función:

def fn1():
    a = """\
def rec(n):
    if n > 10:
        return
    print n
    return rec(n+1)

rec(5)"""

    exec(a)

fn1()

Se produce el mismo error: NameError: el nombre global 'rec' no está definido

7
Headcrab 16 may. 2009 a las 11:21

3 respuestas

La mejor respuesta

Esto funciona para mi:

a = """\
def rec(n):
    if n > 10:
        return
    print n
    return rec(n+1)

rec(5)"""

exec(a)
5
6
7
8
9
10

Todo lo que puedo decir es que probablemente haya un error en su código.

Editar

Aquí tiene

def fn1():
    glob = {}
    a = """\
def rec(n):
    if n > 10:
        return
    print n
    return rec(n+1)

rec(5)"""
    exec(a, glob)

fn1()
4
Unknown 16 may. 2009 a las 08:17

"NameError: el nombre global 'rec' no está definido" significa que está buscando rec en el ámbito global, no en el ámbito local. Parece que está definiendo rec en el ámbito local pero luego intenta ejecutar en el global. Intente imprimir locales () y globales () en el lado de la cadena que está ejecutando.

Más información.

0
Bjorn 16 may. 2009 a las 08:05

Esto funciona para mí (agregado global rec). rec(5) llama a la rec local, pero rec(n+1) llama a una grabación global (que no existe) sin ella.

def fn1():
    a = """global rec
def rec(n):
    if n > 10:
        return
    print n
    return rec(n+1)

rec(5)"""

    exec(a)
3
stephan 16 may. 2009 a las 08:30