In Python, need to clean up all the actions in reverse order inside finally block.
I will explain the requirment in Perl.
sub fun1{
add_1();
verify_1();
add_2();
verify_2();
remove_2();
remove_1();
}
In case verify_2()
throws an exception, add_1()
remains uncleaned.
This is how I handle the cleanup in Perl
sub fun1{
@cleanUpActions = ();
try {
add_1();
push (@cleanUpActions, sub {remove_1()} );
verify_1();
add_2();
push (@cleanUpActions, sub {remove_2()} );
verify_2();
remove_2();
pop @cleanUpActions;
remove_1();
pop @cleanUpActions;
} catch {
BaseException->throw("")
} finally{
foreach my $action (reverse @cleanUps){
&$action;
}
}
}
Tried the same logic in Python.
def r2():
remove_2()
def r1():
remove_1()
clean_list = []
def fun1():
try:
add_1()
clean_list.append(r1)
verify_1()
add_2()
clean_list.append(r2)
verify_2()
remove_2();
clean_list.pop()
remove_1();
clean_list.pop()
except:
raise Exception
finally:
clean_list.reverse()
for func in clean_list:
func()
This above Python code works, but its not that I need. Instead of writing separate def , i would like to add the function block as anonymous func into the list, like I can do in Perl. Python Lambda only accepts expression, does not support multi line body.
Is there any other efficient way to handle such cleanup actions in Python.
Anonymous subs are called "lambdas" in Python.
add_1()
clean_list.append(lambda: remove_1())
verify_1()
That said, you can use the name of a function without ()
as a function pointer.
>>> def f():
... print("foo")
...
>>> x = f
>>> x()
foo
So all you need is
add_1()
clean_list.append(remove_1)
verify_1()
Also note that you can use def
inside of a function, allowing you to create a multi-statement cleanup function.
add_1()
def r1():
remove_1()
clean_list.append(r1)
verify_1()