Есть ли смысл использовать контекстные менеджеры внутри генераторов? - PullRequest
10 голосов
/ 01 июня 2011
from contextlib import contextmanager

@contextmanager
def context():
    print "entering"
    yield
    print "exiting"

def test():
    with context():
        for x in range(10):
            yield x

for x in test():
    if x == 5:
        break  # or raise

output:

entering

Есть ли способ заставить python автоматически вызывать метод context (__exit__) () при прерывании цикла for?Или какой-то другой способ достижения той же цели?То, что я знаю о генераторах и контекстных менеджерах, заставляет меня подозревать, что это невозможно, но это делает контекстные менеджеры довольно бесполезными внутри генераторов, не так ли?Мне кажется, что оператор yield внутри блока with должен поднимать красный флаг, менеджер контекста __exit__ может не работать .

1 Ответ

16 голосов
/ 01 июня 2011

Что ж, вы можете заключить функцию yield в context () в предложение try / finally:

from contextlib import contextmanager

@contextmanager
def context():
    print "entering"
    try:
        yield
    finally:
        print "exiting"

def test():
    with context():
        for x in range(10):
            yield x

for x in test():
    if x == 5:
        break  # or raise

output:

entering
exiting

Edit: Если вы попробуете: help (contextmanager) , он покажет это «типичный» пример использования, где они обертывают выход выражением try / finally.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...