帮别人看代码,偶然遇到这个问题,原来python解释器有一个默认的最大递归次数是999。
举个例子:
def recursion (n) :
if (n <= 1 ):
return
print n
recursion(n - 1 )
print "test 999"
recursion(999 )
print "test 1000"
recursion(1000 )
可以在文件初始位置修改这个最大递归次数,如下:
import sys
sys.setrecursionlimit(10000 )
这时候递归1000次,2000次都不会报错了,但次数很大时比如5000就会报错,又查资料,结论如下:
sys.setrecursionlimit(limit)
Set the maximum depth of the Python interpreter stack to limit. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python. The highest possible limit is platform-dependent. A user may need to set the limit higher when she has a program that requires deep recursion and a platform that supports a higher limit. This should be done with care, because a too-high limit can lead to a crash.
sys.setrecursionlimit()
只是修改解释器在解释时允许的最大递归次数,此外,限制最大递归次数的还和操作系统有关,经过测试:
windows下最大迭代次数约4400次,linux下最大迭代次数约为24900次(python 2.7 64位)
如下代码可以测试最大迭代次数:
import sys
import itertools
class RecursiveBlowup1 :
def __init__ (self) :
self.__init__()
def test_init () :
return RecursiveBlowup1()
class RecursiveBlowup2 :
def __repr__ (self) :
return repr(self)
def test_repr () :
return repr(RecursiveBlowup2())
class RecursiveBlowup4 :
def __add__ (self, x) :
return x + self
def test_add () :
return RecursiveBlowup4() + RecursiveBlowup4()
class RecursiveBlowup5 :
def __getattr__ (self, attr) :
return getattr(self, attr)
def test_getattr () :
return RecursiveBlowup5().attr
class RecursiveBlowup6 :
def __getitem__ (self, item) :
return self[item - 2 ] + self[item - 1 ]
def test_getitem () :
return RecursiveBlowup6()[5 ]
def test_recurse () :
return test_recurse()
def test_cpickle (_cache={}) :
try :
import cPickle
except ImportError:
print "cannot import cPickle, skipped!"
return
l = None
for n in itertools.count():
try :
l = _cache[n]
continue
except KeyError:
for i in range(100 ):
l = [l]
cPickle.dumps(l, protocol=-1 )
_cache[n] = l
def check_limit (n, test_func_name) :
sys.setrecursionlimit(n)
if test_func_name.startswith("test_" ):
print test_func_name[5 :]
else :
print test_func_name
test_func = globals()[test_func_name]
try :
test_func()
except (RuntimeError, AttributeError):
pass
else :
print "Yikes!"
limit = 1000
while 1 :
check_limit(limit, "test_recurse" )
print "Limit of %d is fine" % limit
limit = limit + 100