DYD
DYD

Reputation: 391

Return from parent function in a child function

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

Answers (3)

Viragos
Viragos

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

gekigek99
gekigek99

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

dspencer
dspencer

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

Related Questions