python 最大递归次数 RuntimeError: maximum recursion depth exceeded

转载出处:点击打开链接

帮别人看代码,偶然遇到这个问题,原来python解释器有一个默认的最大递归次数是999。

举个例子:

def recursion(n):
    if (n <= 1):
        return
    print n
    recursion(n - 1)

print "test 999"
recursion(999)   #正常运行

print "test 1000"
recursion(1000)  #报错,RuntimeError: maximum recursion depth exceeded
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可以在文件初始位置修改这个最大递归次数,如下:

import sys
sys.setrecursionlimit(10000)  # set the maximum depth as 10000
  • 1
  • 2
  • 3

这时候递归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  # Already tried and it works, let's save some time
        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()
    # AttributeError can be raised because of the way e.g. PyDict_GetItem()
    # silences all exceptions and returns NULL, which is usually interpreted
    # as "missing attribute".
    except (RuntimeError, AttributeError):
        pass
    else:
        print "Yikes!"

limit = 1000
while 1:
    check_limit(limit, "test_recurse")
    # check_limit(limit, "test_add")
    # check_limit(limit, "test_repr")
    # check_limit(limit, "test_init")
    # check_limit(limit, "test_getattr")
    # check_limit(limit, "test_getitem")
    # check_limit(limit, "test_cpickle")
    print "Limit of %d is fine" % limit
    limit = limit + 100
阅读更多

RuntimeError: maximum recursion depth exceeded

12-04

调用matplotlib画了一个带有sliderbar的统计图,每次拖动sliderbar就更新统计图,更新大概20次左右的时候就会出现下面的bug,哪位大神帮我看看,本人python小白rnrn[code=text]Exception in Tkinter callbackrnTraceback (most recent call last):rn File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__rn return self.func(*args)rn File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 380, in motion_notify_eventrn FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)rn File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 1720, in motion_notify_eventrn guiEvent=guiEvent)rn File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 1343, in __init__rn LocationEvent.__init__(self, name, canvas, x, y, guiEvent=guiEvent)rn File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 1248, in __init__rn axes_list = [a for a in self.canvas.figure.get_axes() if a.in_axes(self)]rn File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 1723, in in_axesrn return self.patch.contains(mouseevent)[0]rn File "C:\Python27\lib\site-packages\matplotlib\patches.py", line 589, in containsrn (mouseevent.x, mouseevent.y))rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 1297, in transform_pointrn return self.transform(np.asarray([point]))[0]rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 1238, in transformrn return self.transform_affine(self.transform_non_affine(values))rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 2175, in transform_affinern return self.get_affine().transform(points)rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 2203, in get_affinern self._a.get_affine().get_matrix()))rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 1666, in __init__rn Affine2DBase.__init__(self, **kwargs)rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 1511, in __init__rn Transform.__init__(self, *args, **kwargs)rn File "C:\Python27\lib\site-packages\matplotlib\transforms.py", line 93, in __init__rn self._parents = WeakValueDictionary()rn File "C:\Python27\lib\weakref.py", line 53, in __init__rn UserDict.UserDict.__init__(self, *args, **kw)rnRuntimeError: maximum recursion depth exceeded[/code]rnrn贴一段关于画图方面的代码,通过Xs和Ys两个数组画统计图,isUpdate表示是否为更新图rn[code=python] ###### draw graph: add patch to the figure ######rn def addBuyerPatch(self,Xs,Ys,isUpdate):rn rn # set the left,right,top and bottom of the rectangles # rn left = Xsrn right = Xs + np.ones(len(left))rn top = np.zeros(len(left))rn bottom = top - Ysrn rn # draw patch and add patch #rn self.buyerXY = np.array([[left,left,right,right], [bottom,top,top,bottom]]).Trn self.buyerBarpath = path.Path.make_compound_path_from_polys(self.buyerXY)rn rn if(isUpdate==0):rn self.buyerPatch = patches.PathPatch(self.buyerBarpath, facecolor='blue', edgecolor='gray', alpha=0.8)rn self.ax.add_patch(self.buyerPatch)rn self.haveBuyerPatch = 1rn return -bottom.min()[/code]

没有更多推荐了,返回首页