Python:协程-StopIteration异常

时间:2018-12-26 05:43:36

标签: python python-3.x generator coroutine stopiteration

我正在尝试使用.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 :(得分:2)

您的协程在首次发送/屈服后退出。这样会生成一个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

我猜你想让协程活着接受尽可能多的发送,直到明确的close

@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异常。