2013-03-12 3 views
1

Я не уверен, что именно происходит в следующем фрагменте кода:Что происходит, когда сопрограмма вызывает исключение?

def coroutine(): 
    lst = [] 
    try: 
     while True: 
      item = (yield lst) 
      if item == 3: 
       raise ValueError 
      print('append {}'.format(item)) 
      lst.append(item) 
    except GeneratorExit: 
     print('GeneratorExit') 

crt = coroutine() 

next(crt) 
print(crt.send(1)) 
print(crt.send(2)) 

try: 
    print(crt.send(3)) 
except ValueError: 
    pass 

print(crt.send(4)) 

Это выходы:

append 1 
[1] 
append 2 
[1, 2] 

Traceback (most recent call last): 
    File "D:\Documents and Settings\Brecht\Desktop\crt.py", line 25, in <module> 
    print(crt.send(4)) 
StopIteration 

При пошаговом через код с помощью отладчика, на raise ValueError, выполнение перескакивает на except GeneratorExit: , но тело этого исключающего предложения не выполняется («GeneratorExit» не печатается). Почему нет?

Помимо этого, я не думаю, что могу каким-либо образом возобновить сопрограмму после того, как она исключила исключение? Есть ли какая-то особая причина не допускать этого? Это было бы полезно, по крайней мере, в моем конкретном случае использования.

+1

Он прыгает туда, но не выполняет его, потому что это значение «ValueError»? – Ryan

+0

@minitech doh, конечно! –

ответ

4

Когда вы выбрасываете исключение, поток кода всегда прерван. Вы не можете возобновить прерванный генератор после того, как вы выбросите в него исключение.

От PEP 342 (Coroutines via Enhanced Generators):

Как и в методе next(), метод send() возвращает следующее значение , выданное посредством генератора-итератора или поднимает StopIteration если генератор выходит нормально, или уже вышел. Если генератор вызывает неперехваченное исключение, он распространяется на вызывающего абонента send().

Как отладчика прыгает на except линии: вы просто бросил исключение и интерпретатор проверяет, если исключение перехватывается этой линии или нет. Поскольку он только поймает GeneratorExit, генератор выйдет в этой точке.

+0

Будет ли вред в возможности возобновить сопрограмму после исключения? –

+0

@BrechtMachiels * Где бы это было? И в каком состоянии? – delnan

+1

@delnan Не имеет значения, если это четко определено –

Смежные вопросы