例外和Python

时间:2011-07-19 22:45:44

标签: python exception

我是Python的新手,我遇到了一个问题,我认为我已经解决了但是它一直在发生。我有类似以下内容。

def funct1()
    dosomestuff
    funct2()

def funct2()
    dosomestuff
    funct3()

def funct3()
    dosomestuff
    funct1()

def exceptionRecovery()
    checksomethings
    funct1() or funct2() or funct3()

try: 
    funct1()
except:
    exceptionRecovery()

现在,我的问题是,这个程序永远不应该退出。 exceptionRecovery应该检查几个东西并根据各种事物的状态启动正确的函数。但是,我仍然在程序中崩溃,这让我感到困惑。有人可以告诉我我做错了吗?

9 个答案:

答案 0 :(得分:9)

你是否有机会获得stackoverflow异常:)?由于python没有尾调用递归优化,因此无法无限地嵌套函数调用。因此,您应该考虑将您的逻辑置于无限循环中。

while True:
    //logic to call func1, 2, 3 or whatever

答案 1 :(得分:7)

您的程序本质上是一个无限递归的程序。你正在以极端的偏见吹走Python的调用栈。

答案 2 :(得分:3)

我...我不确定我是否完全理解为什么事情就像他们一样被束缚在一起。在Python中,至少根据我的经验,“一个永远运行的程序”的标准习惯是这样的:

while True:
  function_1()

您正在设置的是无限递归,它最终将通过解释器的最大递归级别设置,从而导致您无法捕获和忽略的异常。

答案 3 :(得分:3)

这种编程风格似乎期待tail call优化,这在Python中是不受支持的。 Python的调用堆栈会跟踪所有未返回的函数,因为您只是无限地调用新函数,所以您将非常快速地超出堆栈的最大大小,并且您的程序将崩溃。

答案 4 :(得分:3)

您已编码无限循环。更糟糕的是,你无休止地跳入功能。每次跳入函数时,计算机都需要存储位置,以便在完成该函数的执行后跳回。在引起堆栈溢出异常之前,只能存储这么多跳转。

考虑一个while循环,调用你的三个函数。虽然不知道你想要达到什么目标,但很难提出建议。

答案 5 :(得分:2)

您不应该通过从异常处理程序内部调用main来实现循环。尝试更像这样的东西:

while True:
    try:
        func1() or func2() or func3()
    except:
        logger.exception("somthing bad happened")

答案 6 :(得分:1)

一条建议是使用except:非常糟糕。始终尝试指定要捕获的异常类型。

检查this thread有关递归深度的信息!

答案 7 :(得分:1)

我认为约翰是对的,你吹掉了电话堆栈。但是,如果您第一次点击exceptionRecovery函数并且它调用了函数1 2或3会发生什么情况,无论哪种方式它都不再在尝试中,并且因此如果它不在新的尝试中则退出。

答案 8 :(得分:0)

您已使用continuations实施了计划流程。如果您使用Scheme或某些其他语言进行背景编程,那么您可能在过去使用过这种风格而没有任何负面后果。在Python中,使用基于延续的样式将最终导致堆栈溢出,除非您的程序发生足够快的终止以防止它。

如果您以前在其他语言的编程中依赖GOTO语句,您应该知道在Python中,调用函数与“跳转”相同,如在GOTO中,到源中该函数的开头。

了解how the stack works(网上有很多地方可以为您提供帮助)。在代码中使用return语句,这样就可以避免“无限堆栈”。