• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    浅谈Python协程asyncio

    一、协程

    官方描述;
    协程是子例程的更一般形式。 子例程可以在某一点进入并在另一点退出。 协程则可以在许多不同的点上进入、退出和恢复。 它们可通过 async def 语句来实现。 参见 PEP 492。

    # 需要python3.7+
    import asyncio
    
    
    async def main():
        print('hello')
        await asyncio.sleep(1)
        print('world')
    
    asyncio.run(main())
    
    # 打印 "hello",等待 1 秒,再打印 "world"
    

    注意:简单地调用一个协程并不会使其被调度执行,

    直接main() 调用会有问题:

    RuntimeWarning: coroutine 'main' was never awaited
      main()
    RuntimeWarning: Enable tracemalloc to get the object allocation traceback

    def func1():
        print(1)
        ...
        print(2)
        
    def func2():
        print(3)
        ...
        print(4)
    
    func1()
    func2() 
    
    # 结果:1 2 3 4

    实现协程的方法:

    1.1 greenlet实现协程

    # 第三方模块,因此需要安装
    
    pip install greenlet
    from greenlet import greenlet
    
    
    def func1():
        print(1)
        gr2.switch()
        print(2)
        gr2.switch()
    
    
    def func2():
        print(3)
        gr1.switch()
        print(4)
    
    
    gr1 = greenlet(func1)
    gr2 = greenlet(func2)
    
    gr1.switch()
    
    # 结果:1 3 2 4
    

    1.2 yield关键字

    def func1():
        yield 1
        yield from func2()
        yield 2
    
    
    def func2():
        yield 3
        yield 4
    
    f1 = func1()
    for item in f1:
        print(item)
        
    # 结果:1 3 2 4
    

    1.3 asynico装饰器

    python3.4 及之后版本支持

    DeprecationWarning: “@coroutine” decorator is deprecated since Python 3.8, use “async def”
    翻译:@coroutine"装饰器自Python 3.8起已弃用,请使用"async def"代替

    所以这个也不支持。

    import asyncio
    
    @asyncio.coroutine
    def func1():
        print(1)
        yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片
        print(2)
    
    @asyncio.coroutine
    def func2():
        print(3)
        yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片
        print(4)
    
    tasks = [
        asyncio.ensure_future(func1()),
        asyncio.ensure_future(func2())
    ]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    
    # 结果: 1 3 2 4
    

    1.4 async await 关键字

    import asyncio
    
    
    async def func1():
        print(1)
        await asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片
        print(2)
    
    
    async def func2():
        print(3)
        await asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片
        print(4)
    
    tasks = [
        asyncio.ensure_future(func1()),
        asyncio.ensure_future(func2())
    ]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    

    二、协程的意义

    充分利用线程。在一个线程中如果遇到IO等待时间线程不会一直等待,利用空闲时间再去干点其他事情。

    以下载三张图片为例:

    普通方式(同步)下载:

    import time
    import requests
    
    def download_image(url, img_name):
        print("开始下载:", url)
        # 发送网络请求,下载图片
        response = requests.get(url)
        print("下载完成")
        # 图片保存到本地文件
        file_name = str(img_name) + '.png'
        with open(file_name, mode='wb') as file:
            file.write(response.content)
    
    if __name__ == '__main__':
        start = time.time()
        url_list = [
            'https://tse4-mm.cn.bing.net/th/id/OIP.866vRxQ8QvyDsrUuXiu7qwHaNK?w=182h=324c=7o=5pid=1.7',
            'https://tse2-mm.cn.bing.net/th/id/OIP.HUcWtoYPG-z2pu4ityajbAHaKQ?w=182h=252c=7o=5pid=1.7',
            'https://tse2-mm.cn.bing.net/th/id/OIP.MvncR0-Pt9hVxKTdrvD9dAHaNK?w=182h=324c=7o=5pid=1.7',
            'https://tse1-mm.cn.bing.net/th/id/OIP._nGloaeMWbL7NB7Lp6SnXQHaLH?w=182h=273c=7o=5pid=1.7',
            ]
        img_name = 1
        for item in url_list:
            download_image(item, img_name)
            img_name += 1
        end = time.time()
        print(end - start)
        
     # 最终时间:7.25s
    

    协程方式(异步)下载:

    import aiohttp
    import asyncio
    import time
    
    
    async def fetch(session, url):
        print("发送请求:", url)
    
        async with session.get(url, verify_ssl=False) as response:
            content = await response.content.read()
            file_name = url.rsplit('_')[-1]
            # print(file_name)
            with open(file_name, mode='wb') as file_object:
                file_object.write(content)
            print("下载完成")
    
    
    async def main():
        async with aiohttp.ClientSession() as session:
            url_list = [
                'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
                'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
                'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
                'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
            ]
            tasks = [asyncio.ensure_future(fetch(session, url)) for url in url_list]
            await asyncio.wait(tasks)
    
    if __name__ == '__main__':
        start = time.time()
        asyncio.get_event_loop().run_until_complete(main())
        end = time.time()
        print(end - start)
        
    # 结果:0.05s
    

    到此这篇关于浅谈Python协程的文章就介绍到这了,更多相关Python协程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • Python协程asyncio异步编程笔记分享
    • 深入理解python协程
    • 浅谈Python协程
    • python协程用法实例分析
    • javascript实现鼠标拖尾特效
    • JavaScript循环遍历的24个方法,你都知道吗
    • JavaScript实现简单拖拽效果
    • JavaScript 数组去重详解
    • 简单谈谈JavaScript变量提升
    • Python 协程与 JavaScript 协程的对比
    上一篇:Python3接口性能测试实例代码
    下一篇:Python编解码问题及文本文件处理方法详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    浅谈Python协程asyncio 浅谈,Python,协程,asyncio,浅谈,