网络编程-协程-2、生成器

知识点:生成器是一种特殊的迭代器,使用关键字yield来生成就可以,十分简单

1、示例代码:

"""生成器是一种特殊的迭代器,内部实现了__iter__和__next__方法,所以生成器只要要使用关键字yield"""
# 使用生成器做一个菲波那切数列
def test1(num):
    a, b = 0, 1
    flag = 0
    while True:
        if flag < num:
            yield a  # 使用yield关键字即可变为生成器,此时整个test1不能看作是一个函数了,test1会返回一个生成器对象
                     #执行到此句代码时,会暂停代码,当再次执行到此处,会继续上一次运行
            
            a, b = b, a+b
            flag += 1
        else:
            raise StopIteration


obj1 = test1(5)  # 生成器对象
for i in obj1:
    print(i)

运行结果:
0
1
1
2
3

2、使用yield创建多任务:

# 创建任务时,在代码结尾加个yield即可
def test1():
    while True:
            print('test1')
            yield


def test2():
    while True:
            print('test2')
            yield


def main():
    t1 = test1()  # 创建生成器对象
    t2 = test2()  
    while True:  # 通过循环next方法去获取任务里面的值,原理:当next(t1)遇到yield,冻结代码,执行next(t2),遇到yield,冻结代码,执行next(t1)
                 #  所以使用yield实现多任务其实就是俩个任务交替运行,不是真正的同时运行
            next(t1)
            next(t2)


if __name__ == '__main__':
    main()

3、使用greenlet创建多任务,greenlet是对yield的封装:

from greenlet import greenlet
import time
def test1():
    while True:
            print('test1')
            g2.switch()
            time.sleep(1)



def test2():
    while True:
            print('test2')
            g1.switch()
            time.sleep(1)


g1 = greenlet(test1)
g2 = greenlet(test2)
g2.switch()

4、使用gevent创建多任务,gevent是对greenlet的封装,以后若使用协程创建多任务,都是用gevent,前面介绍的是为这个做铺垫的:

"""协程其实就是利用代码中耗时等待的时间去做另外一件事,所以只要在任务中加个耗时间就可以,但是不是使用time里的时间,
    要使用gevent中的耗时时间
"""


def test1():
    for i in range(5):
        print('test1')
        gevent.sleep(1)  # 加一个耗时等待时间


def test2():
    for i in range(5):
        print('test2')
        gevent.sleep(1)


def main():
    g1 = gevent.spawn(test1)  # 调用spawn方法,将任务传进去,
    g2 = gevent.spawn(test2)
    gevent.joinall([g1,g2])  # 使用joinall方法,把创建的任务对象放在一个列表里传进去,这也是一个耗时时间


if __name__ == '__main__':
    main()

运行结果:
test1
test2
test1
test2
test1
test2
原文地址:https://www.cnblogs.com/lz-tester/p/9391188.html