2014-10-09 52 views
0

我写了一个无限递归的斐波那契函数,虽然蟒蛇无法检测到它并抛出最大递归限制时发生错误,当我用try和assert来查看是否fib(30 )等于一些价值,它立即告诉我它不是。它是怎么做到的?它似乎甚至不需要运行fib(30)。蟒蛇 - 断言不知何故立即检测到无限递归

注: 我明白,这只是工作,如果我做

try: 
    assert infiniteFib(30) == 832040 
except: 
    print "done immediately" 

当我这样做只是断言,它会产生约太多递归许多错误,但与尝试停靠在第一个错误。

我很好奇的是,python如何快速地产生一个关于无限递归的错误?难道它不需要达到极限(需要很长时间)来判断它是否是无限的?编辑: 一些要求的代码,但只是要清楚,我不想要一个解决方案的错误(我知道这是错误的,因为我故意排除基本情况),我想知道python如何产生错误很快,当它应该需要更长的时间(如果你这样做fib(30),显然这需要一段时间才能打到最大递归限制,但不知何故,蟒蛇方式之前产生错误则):

def fib(n): 
    return fib(n-1) + fib(n-2) 

try: assert(fib(30) == 832040) 
except: print "done immediately" 
+0

你可以与当前进度分享你的代码吗? – user3 2014-10-09 03:58:38

+1

除非您为fib()函数添加代码并向我们显示错误的详细信息,否则很难说出错。 – user3885927 2014-10-09 03:59:02

+0

我按要求添加了代码,但我不想要如何使代码工作的解决方案,我只想知道python在达到最大递归限制之前如何快速地实现其无限递归错误。 – user3475234 2014-10-09 04:06:10

回答

2

这不是马上完成。你的代码运行直到python达到最大递归深度,并且maximum recursion depth在python中默认设置为1000,以避免堆栈溢出错误。

因此,实际上您的代码会一直运行,直到它达到递归深度1000并且出错RuntimeError: maximum recursion depth exceeded。您可以通过如下修改代码验证这一点:

i=0 
def fib(n): 
    global i 
    i = i + 1 
    print i 
    return fib(n-1) + fib(n-2) 

assert(fib(30) == 832040) 
print i 
print "done immediately" 

在我的机器,我得到最后i值984错误之前出来。

3

原因的代码,你已经证明运行速度很快是因为它捕获了fib在达到递归限制并且不打印回溯时引发的异常。运行到递归限制完全不需要很长时间,但是格式化和打印数百行回溯函数却行。

如果你检查你得到的异常,你会发现它与你正常运行fib时得到的RuntimeError相同,而不是AssertionError。尝试一下,看看发生了什么更好:

try: 
    assert(fib(30) == 832040) 
except Exception as e: 
    print("Got an Exception: %r" % e)