Reputation: 167
I'm making a program that asks the users some questions and uses different functions to react to what the user gives as input. I need to make it such that if the user ever types "Cancel", it will not only end the function they are currently in but even the function that called the prior function.
def func1(x):
func2(x+5)
print 5
def func2(x):
func3(x+5)
print 5
def func3(x):
print x
return
func1(20)
print 10
# 30
# 5
# 5
# 10
So currently this will print 30, exit func3, print 5, exit func2, print 5, exit func1. I need a way for it to just stop after func3 prints 30. Any ideas?
So the desired output would be.
#30
#10
Edit: This is an extremely simplified version, they wouldn't type cancel in this specific code. It would be in a raw_input
.
Upvotes: 1
Views: 191
Reputation: 21934
Raising an exception
quits the function stack just like the way you are describing. So you can have the outermost function try-expect
all the inner functions. If any of the inner function raises an exception
, it will bubble up (i.e it won't execute any of the subsequent code in the stack) until it reaches the outermost function's except
.
def func1(x):
try:
func2(x+5)
print 5
except:
pass
def func2(x):
func3(x+5)
print 5
def func3(x):
print x
raise("Foo") # user's input should drive this.
return
func1(20)
print 10
It reaches till func3
in a normal way. func3
however says it doesn't want the normal execution flow to func2
which cascades it to func1
.
If you don't want to change the function's content you can use the following decorator. It also has the corrections mentioned in the comments.
class UserAbort(Exception):
pass
def swallow(f):
def wrapper(*args):
try:
f(*args)
except UserAbort:
pass
return wrapper
@swallow
def func1(x):
func2(x+5)
print 5
def func2(x):
func3(x+5)
print 5
def func3(x):
print x
raise UserAbort # user's input should drive this.
return
func1(20)
print 10
Upvotes: 3