Exceptions and Python
I'm very new to Python and I have a problem which I thought I had solved but it keeps o开发者_运维技巧ccurring. 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?
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
Your program is essentially an infinitely recursive program. You're blowing away Python's call stack with extreme prejudice.
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.
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.
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.
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")
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!
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.
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".
精彩评论