I'm very new to Python and I have a problem which I thought I had solved but it keeps occurring. I have something similar to the following.
def funct1()
dosomestuff
funct2()
def funct2()
dosomestuff
funct3()
def funct3()
dosomestuff
funct1()
def exceptionRecovery()
checksomethings
funct1() or funct2() or funct3()
try:
funct1()
except:
exceptionRecovery()
Now, my problem is, that this program is NEVER supposed to exit. The exceptionRecovery is supposed to check several things and start the correct function depending on the state of some various things. However, I am still getting crashes out of the program which confuses the hell out of me. Can someone please show me what I am doing wrong?
-
Thank you all for so many helpful comments! I really appreciate it! HOWEVER: This does not solve my problem. These functions are only called one each every few minutes, so I really doubt that the program will ever overflow. I will look at restructuring my program for a while true approach, but that really isn't possible at this time I think.David– David2011年07月20日 02:03:27 +00:00Commented Jul 20, 2011 at 2:03
-
1if restructuring your program isn't an option, fixing it isn't either. When everyone who reads your post says "the problem is that it reaches max recursion depth" and you say "I won't fix the recursion problem" then we're done. We've identified a flaw in your implementation. It needs to be addressed.g.d.d.c– g.d.d.c2011年07月20日 14:16:26 +00:00Commented Jul 20, 2011 at 14:16
9 Answers 9
Do you get a stackoverflow exception per chance :) ? Since python does not have tail-call recursion optimization, you can not infinitely nest function calls. For this reason you should consider putting your logic into an infinite while loop.
while True:
//logic to call func1, 2, 3 or whatever
1 Comment
Your program is essentially an infinitely recursive program. You're blowing away Python's call stack with extreme prejudice.
Comments
I ... am not sure I fully grasp why things are chained together the way they are. In Python, at least in my experience, the standard idiom for "a program that runs forever" is something along these lines:
while True:
function_1()
What you're setting up is infinite recursion, which will eventually pass the interpreter's max recursion level setting, causing an exception you don't get to catch and ignore.
Comments
This programming style seems to expect tail call optimization, which is not supported in Python. Python's call stack keeps track of every function that hasn't returned, and since you're just calling new functions infinitely you'll excede the maximum size of the stack very quickly, and your program will crash.
Comments
You have coded an infinite loop. What's worse us that you are endlessly making jumps into functions. Everytime you jump into a function the computer needs to store the location to jump back to when it has finished execution of that function. Only so many of these jumps can be stored before a stack overflow exception is caused.
Consider a while loop with calls to your three functions inside. Although without knowing what you are trying to achieve it will be difficult to advise.
Comments
You should not implement a loop by calling your main from inside the exception handler. Try something more like this:
while True:
try:
func1() or func2() or func3()
except:
logger.exception("somthing bad happened")
1 Comment
A piece of advice is that using except: is very bad. Always try to specify the type of exception you are catching.
Check this thread about recursion depth!
2 Comments
except: can cause your app to ignore signals from the operating system. At minimum, use except Exception to not catch system-level errors.I think John is right with you blowing away the call stack. However what would happen if you did hit the exceptionRecovery function the first time and it called function 1 2 or 3, either way it is no longer in a try except and would therefore exit if it was not in a new try except.
Comments
You have implemented your program flow using continuations. If you have a background programming in Scheme or certain other languages, then you may have used this style in the past without any negative consequences. In Python, using the continuation-based style the way you did will eventually result in a stack overflow, unless your program happens to terminate quickly enough to prevent it.
If you have previously relied on the GOTO statement in your programming in other languages, you should know that in Python, calling a function is not the same as "jumping", as in GOTO, to the beginning of that function in the source.
Learn how the stack works (there are many places online that can help you with this). Use the return statement in your code, so that you can avoid an "unbounded stack".