Итерируемый и контекстный менеджер Python

Я хочу поведения как такового:

with A() as f:
    for x in f:
        do_something(f)

это правильный способ сделать это?

class A:
    def __enter__(self):
        print "Entering context"

    def __iter__(self):
        for x in ["some","list"]:
            yield x

    def __exit__(self):
        print "Deleting context"

person yayu    schedule 20.10.2014    source источник


Ответы (1)


Ваш метод contextmanager.__enter__ должен возвращать итерируемый объект. Это может быть self:

def __enter__(self):
    print "Entering context"
    return self

См. документацию With Statement Context Manager. :

object.__enter__(self)

Введите контекст времени выполнения, связанный с этим объектом. Оператор with свяжет возвращаемое значение этого метода с целью (целями), указанными в предложении as оператора, если таковые имеются.

поэтому все, что возвращает метод, затем привязывается к имени, заданному как цель as.

Ваш contextmanager.__exit__метод должен иметь возможность принимать исключение, если оно возникло:

def __exit__(self, exc_type, exc_value, traceback):

Если исключения нет, оператор with дает вам три аргумента None.

person Martijn Pieters    schedule 20.10.2014
comment
Если вы просто собираетесь игнорировать любое исключение, было бы понятнее указать это в подписи, приняв def __exit__(self, *args). А может и нет; Я думаю, это вопрос стиля в любом случае. - person abarnert; 21.10.2014