Reputation: 391
I know in a function you can exit the function using return
,
def function():
return
but can you exit a parent function from a child function?
Example:
def function()
print("This is the parent function")
def exit_both():
print("This is the child function")
# Somehow exit this function (exit_both) and exit the parent function (function)
exit_both()
print("This shouldn't print")
function()
print("This should still be able to print")
I tried raising an Exception
, as this answer suggests, but that just exits the whole program.
Upvotes: 4
Views: 1723
Reputation: 621
Solution using wrappers/decorators
class ParentShouldReturnException(Exception):
pass
def return_from_child_wrapper(func):
def wrapper(*args, **kwargs):
print('inside return_from_child_wrapper')
try:
result = func(*args, **kwargs)
except ParentShouldReturnException:
print('ParentShouldReturnException was raised, returning')
return 'forced return'
return result
return wrapper
def force_parent_return_if_none_wrapper(func):
def wrapper(*args, **kwargs):
print('inside force_parent_return_if_none_wrapper')
result = func(*args, **kwargs)
if result is None:
print('raising ParentShouldReturnException')
raise ParentShouldReturnException
return result
return wrapper
@force_parent_return_if_none_wrapper
def func_a(a):
return a
@return_from_child_wrapper
def func_b(input_arg1):
return func_a(input_arg1)
print('example 1 - normal')
result = func_b('nothing interesting')
print(f'{result=}')
print()
print('example 2 - return from child')
result = func_b(None)
print(f'{result=}')
this outputs
example 1 - normal
inside return_from_child_wrapper
inside force_parent_return_if_none_wrapper
result='nothing interesting'
example 2 - return from child
inside return_from_child_wrapper
inside force_parent_return_if_none_wrapper
raising ParentShouldReturnException
ParentShouldReturnException was raised, returning
result='forced return'
Upvotes: 0
Reputation: 313
One solution could be this:
returnflag = False
def function():
global returnflag
print("This is the parent function")
def exit_both():
global returnflag
print("This is the child function")
returnflag = True
return
exit_both()
if returnflag == True:
return
print("This shouldn't print")
function()
print("This should still be able to print")
Or if you don't like to play with global variables you can try this:
def function():
returnflag = False
# or you can use function.returnflag = False -> the result is the same
print("This is the parent function")
def exit_both():
print("This is the child function")
function.returnflag = True
return
exit_both()
if function.returnflag == True:
return
print("This shouldn't print")
function()
print("This should still be able to print")
Upvotes: 0
Reputation: 4481
You can raise an exception from exit_both
, then catch that where you call function
in order to prevent the program being exited. I use a custom exception here as I don't know of a suitable built-in exception and catching Exception
itself is to be avoided.
class MyException(Exception):
pass
def function():
print("This is the parent function")
def exit_both():
print("This is the child function")
raise MyException()
exit_both()
print("This shouldn't print")
try:
function()
except MyException:
# Exited from child function
pass
print("This should still be able to print")
Output:
This is the parent function
This is the child function
This should still be able to print
Upvotes: 5