Python Forum

Full Version: exiting the outer function from the inner function
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello everyone.

In the code below I have simplified a result I'm trying to achieve.
I want to know how I can exit the outer function when the inner function returns a specific choice:

def outer_function():

    def inner_function():

        question = input('Answer here: ')
        if question == 'q':
            return menu()
        else:
            return question

    # if the return from the inner_function is 'menu()',
    # then I want the outer function to terminate as well
    # and not continue

    x = inner_function()
    while True:

        print(f'Here we evaluate a condition based on the {x} that is returned')

        return f'something related to {x}'


def menu():
    print('This is menu.')

    choice = input('Choose: ')
    if choice == '1':
        return outer_function()
    else:
        exit()
Thanks in advance.
You have a few things going on that are unusual.

menu calls outer, outer calls inner, and inner calls menu. That's a recipe for an infinite recursion. I don't think it's needed. Perhaps if you had more specifics about what the functions should do, we could have some suggestions. Right now it seems to be a control flow example, but the control flow looks odd.

Also, there's no reason to have the inner function defined inside the outer. It doesn't reference any variables in the outer function, so better would be to have them independent. That doesn't prevent them from calling each other.
You mentioned that this was a simplified example. If you really need to do this, the common way is using Sentinel values to signal something. It's a value that simply cannot be generated any other way. Here's an example:

>>> def outer():
...   class Sentinel:
...     pass
...   def inner():
...     question = input("Answer here: ")
...     if question == "q":
...       return Sentinel()
...     return question
...   x = inner()
...   if isinstance(x, Sentinel):
...     return
...   while True:
...     print(f"do something with {x}")
...
...
>>> def menu():
...   print("hi i'm a menu")
...   running = True
...   while running:
...     choice = input("Choose: ")
...     if choice == "1":
...       outer()
...     else:
...       running = False
...
>>> menu()
hi i'm a menu
Choose: 1
Answer here: q
Choose: 1
Answer here: q
Choose: 1
Answer here: q
Choose: asdf
The other option is to include state with the function return. Something like:
>>> def outer():
...     def inner():
...         question = input("Answer: ")
...         state = {"response": question}
...         state["next"] = "return" if "q" == question else "work"
...         return state
...     x = inner()
...     if "return" == x["next"]:
...         return
...     while True:
...         print(f"do something with {x}")
...
That version can quickly get very messy if you're not careful, though, and make it very difficult to debug. But the state method is how things like level transitions work in video games.
(Feb-26-2021, 10:14 PM)nilamo Wrote: [ -> ]x = inner()...     if "return" == x["next"]:...         return
Thank you. This helped.
I also did some tweaking to deal with the recursion issue.