python 协程

来源:互联网 发布:广州java培训 编辑:程序博客网 时间:2024/04/29 04:28

yield 关键字可以在表达式中使用, 而且生成器 API 中增加了 .send(value) 方法。 生成器的调用方可以使用 .send(...) 方法发送数据, 发送的数据会成为生成器函数中 yield 表达式的值。 因此, 生成器可以作为协程使用。 协程是指一个过程, 这个过程与调用方协作, 产出由调用方提供的值

协程四个状态:可以使用inspect.getgeneratorstate(...)获取
'GEN_CREATED'  等待开始执行
'GEN_RUNNING' 解释器正在执行
'GEN_SUSPENDED'   yield 表达式处暂停
'GEN_CLOSED'  执行结束

预激活
协程使用之前需要调用next(...)或者send(None)函数,因为生成器还没启动,没在yield语句处暂停,所以一开始无法发送数据。或者可以自己编写预激协程的装饰器

异常 generator.throw(exc_type[, exc_value[, traceback]])
向生成器函数送入一个异常,如果生成器处理了抛出的异常,代码会向前执行到下一个 yield 表达式。 如果生成器没有处理抛出的异常, 异常会向上冒泡, 传到调用方的上下文中。

终止 generator.close()
手动关闭生成器函数,致使生成器在暂停的 yield 表达式处抛出 GeneratorExit 异常。如果生成器没有处理这个异常, 或者抛出了 StopIteration 异常( 通常是指运行到结尾) , 调用方不会报错。 如果收到 GeneratorExit 异常, 生成器一定不能产出值, 否则解释器会抛出 RuntimeError 异常。生成器抛出的其他异常会向上冒泡, 传给调用方。

#协程简单实例,及四个状态def simple_1(a):    print('start')    b = yield a    print('get: b = ', b)    c = yield b    print('get: c = ', c)>>> from inspect import getgeneratorstate>>> c = simple_1(10)>>> getgeneratorstate(c)'GEN_CREATED'>>> c.send(None)# 预激活start10>>> getgeneratorstate(c)'GEN_SUSPENDED'>>> c.send(1)get: b =  11>>> c.send(2)get: c =  2Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration>>> getgeneratorstate(c)'GEN_CLOSED'

#自定义预激协程的装饰器def coroutine(func):    def generator(*args, **kwargs):        primed_func = func(*args, **kwargs)        next(primed_func)        return primed_func    return generator@coroutinedef simple_1(a):    print('start')    b = yield a    print('get: b = ', b)    c = yield b    print('get: c = ', c)>>> g = simple_1(10)start>>> getgeneratorstate(g)'GEN_SUSPENDED'

#协程内没有处理异常,协程会终止,异常向上冒泡,如果试图重新激活协程,会抛出 StopIteration 异常。class DemoException(Exception):pass@coroutinedef grep(pattern):    print("Looking for %s" % pattern)    while True:        line = (yield)        if pattern in line:            print(line)>>> g = grep("python")Looking for python>>> g.send("Yeah, but no, but yeah, but no")>>> g.send("python generators rock!")python generators rock!>>> g.throw(DemoException)Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 5, in grep__main__.DemoException>>> g.send("python generators rock!")Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration

#协程处理异常,错误不向上抛,关闭协程@coroutinedef grep(pattern):    print("Looking for %s" % pattern)    while True:        try:            line = (yield)            if pattern in line:                print(line)        except Exception:            pass>>> from inspect import getgeneratorstate>>> g = grep("python")Looking for python>>> g.send("Yeah, but no, but yeah, but no")>>> g.send("python generators rock!")python generators rock!>>> g.throw(DemoException)>>> g.send("python generators rock!")python generators rock>>> getgeneratorstate(g)'GEN_SUSPENDED'>>> g.close()>>> getgeneratorstate(g)'GEN_CLOSED'









原创粉丝点击