Python 使用全局变量在exec()级别递归
在无意中发现exec()之后,我一直在玩弄exec(),以便更好地理解它的工作原理。我试图让这个讨厌的脚本增加一个全局变量,读取自身,并用新的全局值调用exec,直到满足递归限制。我能想到的最好办法是让一个文件声明全局,然后调用下一个文件(一个完全重复的文件减去变量声明),然后递归调用它自己。下面是第一个的代码:Python 使用全局变量在exec()级别递归,python,python-3.x,recursion,global-variables,Python,Python 3.x,Recursion,Global Variables,在无意中发现exec()之后,我一直在玩弄exec(),以便更好地理解它的工作原理。我试图让这个讨厌的脚本增加一个全局变量,读取自身,并用新的全局值调用exec,直到满足递归限制。我能想到的最好办法是让一个文件声明全局,然后调用下一个文件(一个完全重复的文件减去变量声明),然后递归调用它自己。下面是第一个的代码: # recurse.py def func(): global x x += 1 with open('recurse2.py', 'r') as f:
# 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()
只有一个文件可以达到相同的效果吗?您可以这样做:
# 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是因为我没有引入RecursionError的Python 3.5,但它应该与RecursionError一样工作。)您可以这样做:
# 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是因为我没有引入RecursionError的Python 3.5,但它在RecursionError中也应该起到同样的作用。)是@BrenBarn的优秀解决方案的一个变体,由于打开的文件太多,它失败时会出现RuntimeError(@~500个递归),而不是IOError(@~256个递归): #递归e.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
)。是@BrenBarn优秀解决方案的一个变体,由于打开的文件太多,它会导致运行时错误(@~500次递归)而不是IOError(@~256次递归)失败:
#递归e.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
)。在我的系统上,它不会因递归深度而失败,它会失败:OSError:[Errno 24]打开的文件太多:“recurse.py”(或Python 2中的IOError)--我意识到这对于每个系统都是不同的,但IOError是可以预防的。在我的系统上,它不会因为递归深度而失败,它会因为:OSError:[Errno 24]太多打开的文件而失败:“recurse.py”(或Python 2中的IOError)--我意识到这对于每个系统都是不同的,但IOError是可以预防的。啊,我没有注意到潜在的IOError问题,因为我在过去提高了打开文件的限制。说得好!啊,我没有注意到潜在的IOError问题,因为我在过去提高了打开文件的限制。说得好!