2015-04-17 4 views
5

Я хочу что-то вроде этого:Как создать контекстный менеджер с петлей внутри?

from contextlib import contextmanager 

@contextmanager 
def loop(seq): 
    for i in seq: 
     try: 
      do_setup(i) 
      yield # with body executes here 
      do_cleanup(i) 
     except CustomError as e: 
      print(e) 

with loop([1,2,3]): 
    do_something_else() 
    do_whatever() 

Но contextmanager не работает, потому что он ожидает, что генератор, чтобы получить ровно один раз.

Причина, по которой я хочу это, заключается в том, что я в основном хочу сделать свой собственный для цикла. У меня есть модифицированный IPython, который используется для контроля тестового оборудования. Очевидно, что это полный Python REPL, но большую часть времени пользователь просто вызывает предопределенные функции (похожие на подсказки Bash), и пользователь не должен быть программистом или знаком с Python. Для каждой итерации должен быть способ перебрать некоторый произвольный код с установкой/очисткой и обработкой исключений, и должно быть примерно так же просто напечатать, как указано выше с помощью инструкции.

ответ

7

Я думаю, что генератор работает лучше здесь:

def loop(seq): 
    for i in seq: 
     try: 
      print('before') 
      yield i # with body executes here 
      print('after') 
     except CustomError as e: 
      print(e) 

for i in loop([1,2,3]): 
    print(i) 
    print('code') 

даст:

before 
1 
code 
after 
before 
2 
code 
after 
before 
3 
code 
after 

Python входит и выходит из with блок только один раз, так что вы не можете иметь логику Int на вход/выход шаги, которые будут выполняться повторно.

+0

Я знал, что это будет так просто. Благодаря! – jpkotta