Написание контекстного менеджера на Python, который сам использует оператор with

Я пытаюсь написать менеджер контекста, который использует другие менеджеры контекста, поэтому клиентам не нужно знать весь рецепт, а только интерфейс, который я представляю. Я не могу сделать это с помощью@contextmanager-код после вызова yieldне выполняется, если вас прерывает исключение, поэтому мне нужно использовать менеджер на основе класса -.

Вот небольшой пример скрипта:

from contextlib import contextmanager
import pprint

d = {}

@contextmanager
def simple(arg, val):
    print "enter", arg
    d[arg] = val
    yield
    print "exit", arg
    del d[arg]

class compl(object):
    def __init__(self, arg, val):
        self.arg=arg
        self.val=val

    def __enter__(self):
        with simple("one",1):
            with simple("two",2):
                print "enter complex", self.arg
                d[self.arg] = self.val

    def __exit__(self,*args):
        print "exit complex", self.arg
        del d[self.arg]

print "before"
print d
print ""

with compl("three",3):
    print d
    print ""

print "after"
print d
print ""

Это выводит это:

before
{}

enter one
enter two
enter complex three
exit two
exit one
{'three': 3}

exit complex three
after
{}

Я хочу, чтобы он выводил это:

before
{}

enter one
enter two
enter complex three
{'one': 1, 'three': 3, 'two': 2}

exit complex three
exit two
exit one
after
{}

Есть ли способ сказать диспетчеру контекста на основе класса -обернуть себя другими диспетчерами контекста?

12
задан Andrew Roberts 11 July 2012 в 20:34
поделиться