2016-03-09 5 views
1

У меня есть много блоков кода, как это:Как упростить такой код Python?

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) 

Я надеюсь написать некоторый магический код, как это:

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

Возможно ли это?

+0

Почему бы не объединить их как внутри одного 'try' и «наконец»? – legends2k

ответ

4

Если вы не можете или не хотите реализовать протокол контекста для a и b, вы можете использовать contextlib средства, чтобы сделать контекст:

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 
+0

upvoted (собирался написать, что после охоты ссылки) –

3

Пусть классы a и b реализуют протокол контекста менеджера, а также использовать with statement:

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

Теперь, если get_a и get_b вернулись открытые дескрипторы файлов, они будут автоматически закрыты в конце блока , Если возвращаемые значения имеют собственный класс, этот класс должен иметь __enter__ and __exit__ magic methods.