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

Handling cleanup actions in python by using anonymous function in list

在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 ,而是想将功能块作为匿名 func 添加到列表中,就像我在 Perl 中所做的那样。 Python Lambda 只接受表达式,不支持多行正文。

在Python.

中是否有任何其他有效的方法来处理此类清理操作

匿名订阅在 Python 中称为“lambda”。

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