zoukankan      html  css  js  c++  java
  • 网络编程-协程-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
  • 相关阅读:
    [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例
    玩转Asp.net MVC 的八个扩展点
    float实例讲解
    C#高性能TCP服务的多种实现方式
    如何把SQLServer数据库从高版本降级到低版本?
    ASP.NET MVC Area使用-将Area设置成独立项目
    如何使用ping和tracert命令测试网站访问速度
    ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
    MVC Action Filter
    c#中单元测试
  • 原文地址:https://www.cnblogs.com/lz-tester/p/9391188.html
Copyright © 2011-2022 走看看