Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将exec()与递归函数一起使用_Python_Recursion_Exec - Fatal编程技术网

Python 将exec()与递归函数一起使用

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()

我想执行一些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()
    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中定义

你可以做几件事:

  • 对局部和全局使用相同的词典。ie“
    exec s in locals(),locals()
    ”(或者更好,只需使用您自己的dict)。仅提供globals()dict具有相同的效果-即“
    exec s in mydict
    ” #
  • 将func放在自己的函数中,以便创建闭包。乙二醇

    s="""
    def go():
        def factorial(x):
            if x==0: return 1
            return x*factorial(x-1)
        print factorial(10)
    go()"""
    
  • 强制函数进入globals()而不是局部变量,方法是放入“global funcname”指令,如


  • @Headcrab,因为它提供了一个可编辑的全局和局部词典。locals()提供了一个无法更改“真实”局部变量的字典。您的意思是,如果“全局变量”不存在,exec将使用默认的只读变量,而“rec”不能添加到其中(因为它是只读的),这就是为什么会发生错误?@Headcrab,我相信这是正确的。Exec假设对变量的调用是全局的,因为它看不到它被包装在函数中。真正让我困惑的是,为什么exec(a,globals())似乎可以工作,这表明存在局部变量()问题。实际上,局部变量是只读的与此无关——它会发生在任何时候,只要你使用一个单独的局部变量和全局变量字典。{},{}中的exec将有相同的问题。exec(a,globals())之所以有效,是因为它与exec(a,globals(),globals())相同,所以本地定义也被放入globals中。请告诉我此exec字符串不是用户输入的。