带有全局变量的exec()级递归

2024-09-29 19:33:17 发布

您现在位置:Python中文网/ 问答频道 /正文

在遇到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()

只有一个文件能达到同样的效果吗?你知道吗


Tags: 文件py声明readdefaswithopen
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。只是程序本身在调用func之前将x设置为零。因此,传入起始值x没有任何效果:您正在执行的代码将设置一个新值x。在这个新版本中,try/except块测试名称是否已经存在,然后将其初始化为零。你知道吗

(我在这里使用RuntimeError是因为我没有引入递归错误的Python3.5,但是它应该和递归错误一样工作。)

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

#递归.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)。你知道吗

相关问题 更多 >

    热门问题