使用列表中的匿名函数处理python中的清理操作



在Python中,需要以相反的顺序清理finally块内的所有操作。

我将用Perl解释这个要求。

sub fun1{
add_1();
verify_1();
add_2();
verify_2();
remove_2();
remove_1();
}

如果verify_2()抛出异常,则add_1()保持未清除状态。

这就是我在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;
}
}
}

在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()

上面的Python代码是有效的,但我不需要它。我不想写单独的def,而是想把函数块作为匿名函数添加到列表中,就像我在Perl中可以做的那样。Python Lambda只接受表达式,不支持多行体。

有没有其他有效的方法来处理Python中的此类清理操作。

匿名子类被称为"lambdas";在Python中。

add_1()
clean_list.append(lambda: remove_1())
verify_1()

也就是说,您可以使用不带()的函数的名称作为函数指针。

>>> def f():
...    print("foo")
...
>>> x = f
>>> x()
foo

所以你只需要

add_1()
clean_list.append(remove_1)
verify_1()

还要注意,您可以在函数内部使用def,从而可以创建多语句清理函数。

add_1()
def r1():
remove_1()
clean_list.append(r1)
verify_1()

最新更新