如何简化这种Python代码?

How to simplify this kind of Python code?

我有很多这样的代码块:

1
2
3
4
5
6
7
8
9
10
11
12
13
try:
  a = get_a()
  try:
    b = get_b()

    # varying codes here, where a and b are used

  finally:
    if b:
      cleanup(b)
finally:
  if a:
    cleanup(a)

我希望写一些像这样的魔术代码:

1
2
some_magic:
  # varying codes here, where a and b are also available

这可能吗?


如果您不能或不想为ab实现上下文协议,则可以使用contextlib工具创建上下文:

1
2
3
4
5
6
7
8
9
10
11
12
13
from contextlib import contextmanager

@contextmanager
def managed(a):
    try:
        yield a
    finally:
        if a:
            cleanup(a)

with managed(get_a()) as a, managed(get_b()) as b:
    # do something here
    pass


ab的类实现上下文管理器协议,并使用with语句:

1
2
with get_a() as a, get_b() as b:
    do_magic

现在,如果get_aget_b返回打开的文件句柄,它们将在块结束时自动关闭。 如果返回的值是自定义类,则该类应具有__enter____exit__魔术方法。