我是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应该检查几个东西并根据各种事物的状态启动正确的函数。但是,我仍然在程序中崩溃,这让我感到困惑。有人可以告诉我我做错了吗?
答案 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
语句,这样就可以避免“无限堆栈”。