【问题标题】:python - assert somehow immediately detects infinite recursionpython - 断言以某种方式立即检测到无限递归
【发布时间】:2014-10-09 03:55:47
【问题描述】:

我写了一个无限递归的斐波那契函数,虽然 python 无法检测到它并在达到最大递归限制时抛出错误,但当我使用 try 和 assert 来查看 fib(30) 是否等于某个值时,它立即告诉我不是。它是怎么做到的?似乎它甚至不需要运行 fib(30)。

注意: 我意识到这只有在我这样做时才有效

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

当我只做断言时,它会产生很多关于递归过多的错误,但尝试它会在第一个错误处停止。

我很好奇的是,python 是如何如此迅速地产生关于无限递归的错误的?是不是需要达到极限(这需要很长时间)才能判断它是否是无限的?

编辑: 一些请求的代码,但为了清楚起见,我不想要错误的解决方案(我知道这是错误的,因为我故意排除了基本情况),我想知道 python 如何在需要更长的时间时如此快速地产生错误(如果你这样做fib(30),显然需要一段时间才能达到最大递归限制,但不知何故python会在此之前产生错误):

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

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

【问题讨论】:

  • 你能分享一下你的代码吗?
  • 除非您为您的 fib() 函数添加代码并向我们展示错误的详细信息,否则很难分辨出哪里出了问题。
  • 我按要求添加了代码,但我不想要如何使代码工作的解决方案,我只想知道python如何如此迅速地产生无限递归错误,甚至之前达到最大递归限制。
  • 您是否尝试将打印语句添加到fib-函数?也许它实际上是递归的,直到最大深度,它太快了你没有注意到(它真的不应该花太长时间)。

标签: python recursion try-catch infinite-loop assert


【解决方案1】:

您显示的代码运行迅速的原因是它捕获了fib 在达到递归限制时引发的异常并且不打印回溯。运行到递归限制根本不需要很长时间,但格式化和打印数百行回溯却需要。

如果你检查你得到的异常,你会发现它与你正常运行fib 时得到的RuntimeError 相同,而不是AssertionError。试试这个,看看效果更好:

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

【讨论】:

    【解决方案2】:

    这不是立即完成的。您的代码会一直运行到 python 达到最大递归深度,并且在 python 中默认将maximum recursion depth 设置为 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,然后才出现错误。

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多