zoukankan      html  css  js  c++  java
  • 【Python】生成器

    生成器是一种特殊的迭代器

    # 斐波那契数列 10
    def create_num(all_num):
    
        a, b = 0, 1
    
        current_num = 0
    
        while current_num < all_num:
          #  print(a)
            yield a  # 如果一个函数中有yield语句,那么这个就不在是函数,而是一个生成器的模板
            a, b = b, a+b
            current_num += 1
    
    # 调用的时候,发现有yield,不是调用函数,是创建一个生成器对象
    obj = create_num(10)
    
    for i in obj:
        print(i)
    
    # send
    def create_num(all_num):
        a, b = 0, 1
        current_num = 0
        while current_num < all_num:
            ret = yield a
            print(">>>ret>>>", ret)
            a, b = b, b+a
            current_num ++ 1
    
    obj = create_num(10)
    
    # obj.send(None)  # send一般不会放到第一次启动生成器,如果非要这样做 那么传递None
    
    ret = next(obj)
    print(ret)
    
    # send里面的数据会 传递给第5行,当作yield a 的结果,然后ret保存这个结果...
    # send的结果是下一次调用yield时,yield后面的值
    ret = obj.send("haha")
    print(ret)
    

    yield 实现多任务, 协程

    # 协程,调用任务就像调用函数一样,使用资源最少(进程 > 线程 > 协程)
    import time
    
    def task_1():
        while True:
            print("---1---")
            time.sleep(0.1)
            yield
    
    
    def task_2():
        while True:
            print("---2---")
            time.sleep(0.1)
            yield
    
    
    def main():
        t1 = task_1()
        t2 = task_2()
    
        while True:
            next(t1)
            next(t2)
    
    
    if __name__ == '__main__':
        main()
    
    
    
    ## greenlet
    
    
    # 安装 
    pip install greenlet
    
    from greenlet import greenlet
    import time
    
    def test1():
        while True:
            print("---a---")
            gr2.switch()
            time.sleep(0.5)
    
    def test2():
        while True:
            print("bbbb")
            gr1.switch()
            time.sleep(0.5)
    
    gr1 = greenlet(test1)
    gr2 = greenlet(test2)
    
    gr1.switch()
    

    gevent的使用

    # pip install gevent
    
    import  gevent
    import time
    # 遇到耗时等待,自动切换任务
    from gevent import monkey
    
    monkey.patch_all()  # 耗时操作不用修改,可以使用 time.sleep 完成耗时,而非 gevent.sleep
    
    def f1(n):
        for i in range(n):
            print(gevent.getcurrent(), i)
            time.sleep(0.5)
            # gevent.sleep(0.5)
    
    def f2(n):
        for i in range(n):
            print(gevent.getcurrent(), i)
            gevent.sleep(0.5)  # gevent 的耗时操作
    
    def f3(n):
        for i in range(n):
            print(gevent.getcurrent(), i)
            gevent.sleep(0.5)
    
    # g1 = gevent.spawn(f1, 5)
    # g2 = gevent.spawn(f2, 5)
    # g3 = gevent.spawn(f3, 5)
    #
    # g1.join()
    # g2.join()
    # g3.join()
    
    gevent.joinall([
        gevent.spawn(f1, 5),
        gevent.spawn(f2, 5),
        gevent.spawn(f3, 5)
    ])
    

    gevent 怎么用?

    from gevent import monkey
    import gevent
    import random
    import time
    
    
    # 有耗时操作时需要
    monkey.patch_all()  # 将程序中用到的耗时操作的代码,换为gevent中自己实现的模块
    
    def coroutine_work(coroutine_name):
        for i in range(10):
            print(coroutine_name, i)
            time.sleep(random.random())
    
    gevent.joinall([
        gevent.spawn(coroutine_work, "work1"),
        gevent.spawn(coroutine_work, "work2")
    ])
    

    协程图片下载器

    import urllib.request
    import gevent
    from gevent import monkey
    
    monkey.patch_all()
    
    
    def downloader(url, name):
        req = urllib.request.urlopen(url)
        img_content = req.read()
        with open(name, "wb") as f:
            f.write(img_content)
    
    def main():
        gevent.joinall([
            gevent.spawn(downloader, "https://rpic.douyucdn.cn/asrpic/191118/1554733_6854945_7c3f7_2_1502.jpg/webpdy1", "1.jpg"),
            gevent.spawn(downloader, "https://rpic.douyucdn.cn/asrpic/191118/1282190_3853457_1abda_2_1450.jpg/webpdy1", "2.jpg")
        ])
    if __name__ == '__main__':
        main()
    
  • 相关阅读:
    linux上安装mysql
    Linux上安装elasticsearch
    解决pyhton aiohttp ssl:None [[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
    mysql数据库的数据变更事件获取以及相关数据
    [天下小黑盒]打地鼠小助手
    看到当年自己学SQL Server 的笔记
    CodeFirst EF中导航属性的个人理解
    在Win10下如何安装IMSL6.0
    商品中台三期压测
    压测
  • 原文地址:https://www.cnblogs.com/liudianer/p/11849955.html
Copyright © 2011-2022 走看看