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.