Python 将exec()与递归函数一起使用
我想执行一些Python代码,在运行时键入,因此我得到字符串并调用 exec(pp,globals(),locals()) 其中,pp是字符串。它工作得很好,除了递归调用,例如。g、 ,例如,此代码正常:Python 将exec()与递归函数一起使用,python,recursion,exec,Python,Recursion,Exec,我想执行一些Python代码,在运行时键入,因此我得到字符串并调用 exec(pp,globals(),locals()) 其中,pp是字符串。它工作得很好,除了递归调用,例如。g、 ,例如,此代码正常: def horse(): robot.step() robot.step() robot.turn(-1) robot.step() while True: horse() 但这不是: def horse(): robot.step()
def horse():
robot.step()
robot.step()
robot.turn(-1)
robot.step()
while True:
horse()
但这不是:
def horse():
robot.step()
robot.step()
robot.turn(-1)
robot.step()
horse()
horse()
NameError:全局名称“horse”不正确
明确的
有没有一种方法也可以运行递归代码
更新
a = """\
def rec(n):
if n > 10:
return
print n
return rec(n+1)
rec(5)"""
exec(a)
如果放在顶层就可以工作。但如果在函数中移动:
def fn1():
a = """\
def rec(n):
if n > 10:
return
print n
return rec(n+1)
rec(5)"""
exec(a)
fn1()
出现相同的错误:NameError:未定义全局名称“rec”它适用于我:
a = """\
def rec(n):
if n > 10:
return
print n
return rec(n+1)
rec(5)"""
exec(a)
5
6
7
8
9
10
我所能说的是,您的代码中可能有一个bug
编辑
给你
def fn1():
glob = {}
a = """\
def rec(n):
if n > 10:
return
print n
return rec(n+1)
rec(5)"""
exec(a, glob)
fn1()
“NameError:未定义全局名称‘rec’”表示它正在全局范围而不是本地范围中查找rec。看起来它在本地范围内定义rec,但随后尝试在全局范围内执行。尝试在正在执行的字符串中打印locals()和globals()
这对我很有用(添加了全局rec
)rec(5)
调用本地rec
,但是rec(n+1)
调用没有它的全局rec(不存在)
def fn1():
a = """global rec
def rec(n):
if n > 10:
return
print n
return rec(n+1)
rec(5)"""
exec(a)
这一点一开始也让我感到惊讶,似乎是一个奇怪的情况,exec的行为既不像顶级定义,也不像封闭函数中的定义。看起来正在发生的是,函数定义正在您传入的locals()dict中执行。但是,定义的函数实际上没有访问此本地指令的权限 通常,如果在顶层定义函数,则局部函数和全局函数是相同的,因此函数在中可见,因为它们可以在全局函数中看到函数 当一个函数在另一个函数的作用域中定义时,python会注意到它是在函数中访问的,并创建一个闭包,以便“horse”映射到外部作用域中的绑定 在这里,这是一个奇怪的情况。exec的行为就像定义是顶级的一样,因此不会创建闭包。但是,由于局部变量与全局变量不同,因此该定义不适用于函数可以访问它的地方——它只在不可访问的外部局部变量dict中定义 你可以做几件事:
exec s in locals(),locals()
”(或者更好,只需使用您自己的dict)。仅提供globals()dict具有相同的效果-即“exec s in mydict
”
#s="""
def go():
def factorial(x):
if x==0: return 1
return x*factorial(x-1)
print factorial(10)
go()"""
@Headcrab,因为它提供了一个可编辑的全局和局部词典。locals()提供了一个无法更改“真实”局部变量的字典。您的意思是,如果“全局变量”不存在,exec将使用默认的只读变量,而“rec”不能添加到其中(因为它是只读的),这就是为什么会发生错误?@Headcrab,我相信这是正确的。Exec假设对变量的调用是全局的,因为它看不到它被包装在函数中。真正让我困惑的是,为什么exec(a,globals())似乎可以工作,这表明存在局部变量()问题。实际上,局部变量是只读的与此无关——它会发生在任何时候,只要你使用一个单独的局部变量和全局变量字典。{},{}中的exec将有相同的问题。exec(a,globals())之所以有效,是因为它与exec(a,globals(),globals())相同,所以本地定义也被放入globals中。请告诉我此exec字符串不是用户输入的。