Python: сопрограммы - исключение StopIteration - PullRequest
0 голосов
/ 26 декабря 2018

Я пытаюсь скормить словарь, используя .send().И мой фрагмент кода ниже

def coroutine(func):
    def start(*args, **kwargs):
        cr = func(*args, **kwargs)
        next(cr)
        return cr
    return start

@coroutine
def putd(di):

    print("via coroutines adding a key : value to dictionary")

    try:
        item = yield
        for key, value in item.items():
            if key in di:
                print("Key : {0} already exists".format(key))
            else:
                di[key] = value
        print(di)
    except StopIteration :
        print("yield frame got closed")


di = {}
gobj = putd(di)
gobj.send({"plan" : "shuttle"})
gobj.close()

И я считаю, что я правильно обрабатываю exception, но все же я получаю StopIteration исключение.

scratch.py
Traceback (most recent call last):
via coroutines adding a key : value to dictionary
{'plan': 'shuttle'}
File "scratch.py", line 39, in <module>
    gobj.send({"plan" : "shuttle"})
StopIteration

Process finished with exit code 1

Я не обрабатываю этоПравильно исключение или я что-то упустил?Любая помощь с благодарностью.

1 Ответ

0 голосов
/ 26 декабря 2018

Ваша сопрограмма выходит после первой отправки / выхода.Это генерирует StopIteration, и вы не можете обработать его в самой сопрограмме, но только при вызове send.Из документов:

Метод send () возвращает следующее значение, полученное генератором, или вызывает StopIteration, если генератор выходит без выдачи другого значения.

@coroutine
def putd(di):

    print("via coroutines adding a key : value to dictionary")

    try:
        item = yield
        for key, value in item.items():
            if key in di:
                print("Key : {0} already exists".format(key))
            else:
                di[key] = value
        print(di)
    except StopIteration :
        print("yield frame got closed")
    # here is an implicit  return None  which terminates the coroutine

Полагаю, вы хотите, чтобы сопрограмма оставалась в живых, принимая столько посылок, сколько вы хотите, до явного закрытия :

@coroutine
def putd(di):

    print("via coroutines adding a key : value to dictionary")

    try:
        while True:
            item = yield
            for key, value in item.items():
                if key in di: 
                    print("Key : {0} already exists".format(key))
                else:
                    di[key] = value
            print(di)
    except GeneratorExit:
        print("yield frame got closed")

Обратите внимание, что теперь исключение GeneratorExit перехвачено.

...