Home > Blockchain >  End a running function using inner function
End a running function using inner function

Time:10-26

I want the f2 to end not itself, but rather completely the parent function f1 while being executed, with a command. I know that return is used to end a function, but it doesn't work here at a sub-level.

So my question is what are these commands (or sets of lines) and how can I implement them in my code? Example snippet here:

def f1:
    do something
    def f2:
        do something
        # need a command here
    f2()
    do something

f1()

It is noteworthy that the code shall be running a while True: loop at the time of discontinuing function. I used tkinter library button to execute a sub function (which means that the sub-function cannot return a value to a variable), but am unable to end the main function from within that set of code.

here is the tkinter code:

tk.Button(root, text='Click me', command=f2)

Here command = f2 executes f2() when tk.Button is pressed, but the value is not returned anywhere. Probably a local or global variable flag can be used inside f2...

Way to quit the most outer function from an inner function? -- This doesn't solve my problem since I must not define a class or error in my code. Is there another method to do so?

CodePudding user response:

One way can be to raise an exception from f2, then catch that exception in f1 and then return early:

def f1():
    # do something
    def f2():
        print('Hello')
        # need a command here
        raise StopIteration()
        print('World!')

    try:
        f2()
    except StopIteration:
        return

    print('World')
    # do something

f1()

Outputs:

Hello

I'm not exactly sure where you're defining the while loop mentioned. If it's outside of f1 entirely, I'd delegate handling of the error within such a loop itself - or you could even wrap the while loop with a try-except if absolutely needed. If you go with latter approach, I'd suggest creating a custom exception class and then catching that specific error; this way you can be sure you're handling only the error that you've raised from within f2 for example.

CodePudding user response:

There are a couple of ways I would tackle this - and it depends on the complexity of the problem.

Simple calculations can be achieved like so:

def foo(*args,**kwargs):
    bar = lambda ... : ...
    do something
    final = bar(x)
    return final   

foo()

If the function has added complexity, it makes sense to use a class (or classes depending on the complexity) like so:

class thing_youre_classifying(object):
    def __init__(self):
        ...

    def __any_other_boilerplate_methods_needed__(self):
        ...

    def foo(self):
        do something

    def bar(self):
        do something
        x = f1()

thing = thing_youre_classifying()
thing.bar()

This is mostly for readability (and probably other important things).

Or, if foo and bar are wildly different (say in foo you're parsing a database and bar you're doing statistical analysis), you'll want to check out class inheritance.

class foo(object):
    def __init__(self, *args, **kwargs)
        initialize each instance of foo with args and kwargs

class bar(foo):
    def __init__(self):
        foo.__init__(self, *args, **kwargs)

instance = bar()
instance.foo()

I want to point out that I did not include *args or **kwargs in bar's boilerplate init function. That could also underline the difference between foo and bar.

The last thing that comes to mind is using decorators.

"One of the main uses of decorators is that they allow us to add functionality to existing functions, without modifying the original function. This capability extends to class methods as well." -anonymous professor

def foo():
    def modifier():
        return foo.method_you_want()
    return modifier

@foo
def bar():
    do something

My gut tells me decorators are going to be the cleanest way to do this.

  • Related