使用全局变量在exec()级别递归

时间:2016-07-02 20:00:46

标签: python python-3.x recursion global-variables

绊倒this question后,我一直在玩exec()以更好地了解它是如何工作的。我试图让脚本憎恶增加一个全局变量,读取它自己,并用新的全局值调用exec,直到满足递归限制。我能想到的最好的方法是让一个文件声明全局,然后调用下一个文件(一个完全重复的减去变量声明),然后递归调用自己。这是第一个代码:

# recurse.py

def func():
    global x
    x += 1
    with open('recurse2.py', 'r') as f:    
        try:
            exec(f.read(), {'x': x})
        except RecursionError:
            print('maximum recursion depth reached at', x)

x = 0
func()

这是它执行的文件,它将自行执行:

# recurse2.py

def func():
    global x
    x += 1
    with open('recurse2.py', 'r') as f:    
        try:
            exec(f.read(), {'x': x})
        except RecursionError:
            print('maximum recursion depth reached at', x)

func()

仅使用一个文件是否可以达到相同的效果?

2 个答案:

答案 0 :(得分:2)

你可以这样做:

# recurse.py

def func():
    global x
    x += 1
    with open('recurse.py', 'r') as f:    
        try:
            exec(f.read(), {'x': x})
        except RuntimeError:
            print('maximum recursion depth reached at', x)

try:
    x
except NameError:
    x = 0
func()

您的初始示例的问题并非真正针对exec。只是程序本身在调用x之前将func设置为零。因此,传入x的起始值无效:您执行的代码无论如何都会设置x的新值。在这个新版本中,try / except块在将名称初始化为零之前测试名称是否已存在。

(我在这里使用了RuntimeError,因为我没有引入RecursionError的Python 3.5,但它应该与RecursionError一样。)

答案 1 :(得分:2)

由于太多文件被打开,@ BrenBarn的优秀解决方案因RuntimeError(@ ~500递归)而不是IOError(@ ~256递归)而失败:

#recurse.py

def func():
    global x
    x += 1
    with open('recurse.py') as source:
        string = source.read()
    try:
        exec(string, {'x': x})
    except RuntimeError:
        print('maximum recursion depth reached at', x)

try:
    x
except NameError:
    x = 0

func()

但是,您也可以根据需要扩展递归堆栈(sys.setrecursionlimit())和/或打开文件限制(ulimit -n)。