协程之asyncio模块

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。

asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO。

0、目录

1、协程利用单任务运行yield from
2、协程利用单任务运行async + await
3、协程利用多任务运行async + await
4、协程利用多任务运行async + await 并且获取返回值单个参数
5、协程利用多任务运行async + await 并且多任务获取返回值
6、协程利用多任务运行async + await,并且按照顺序获取返回值
7、asyncio使用协程进行http访问

1、协程利用单任务运行yield from

import asyncio

def hello():
    print('Hello Start')
    r = yield from asyncio.sleep(1)
    print('Hello End')

if __name__ == '__main__':
    # 获取事件循环的对象
    loop = asyncio.get_event_loop()
    # 增加处理函数到事件循环里面
    loop.run_until_complete(hello())
    loop.close()

# 运行结果
Hello Start
Hello End

2、协程利用单任务运行async + await

import asyncio

async def hello():
    print('Hello Start')
    r = await asyncio.sleep(1)
    print('Hello End')

if __name__ == '__main__':
    # 获取事件循环的对象
    loop = asyncio.get_event_loop()
    # 增加处理函数到事件循环里面
    loop.run_until_complete(hello())
    loop.close()

3、协程利用多任务运行async + await

import asyncio

async def hello():
    print('Hello Start')
    r = await asyncio.sleep(1)
    print('Hello End')

if __name__ == '__main__':
    # 获取事件循环的对象
    loop = asyncio.get_event_loop()
    # 增加处理函数到事件循环里面
    loop.run_until_complete(asyncio.wait([hello(), hello()]))
    loop.close()

4、协程利用多任务运行async + await 并且获取返回值单个参数

import asyncio

async def hello():
    print('Hello Start')
    await asyncio.sleep(1)
    print('Hello End')
    return 'done'

if __name__ == '__main__':
    # 获取事件循环的对象
    loop = asyncio.get_event_loop()

    # 创建一个运行任务
    task = loop.create_task(hello())
    # 增加处理函数到事件循环里面
    loop.run_until_complete(task)

    ret = task.result()
    print(ret)
    loop.close()

5、协程利用多任务运行async + await 并且多任务获取返回值

import asyncio

async def hello(name):
    print('Hello Start')
    await asyncio.sleep(1)
    print('Hello End')
    return 'done', name

if __name__ == '__main__':
    # 获取事件循环的对象
    loop = asyncio.get_event_loop()

    # 创建一个运行任务
    task1 = loop.create_task(hello('li1'))
    task2 = loop.create_task(hello('li2'))

    task_list = [task1, task2]

    tasks = asyncio.wait(task_list)
    # 增加处理函数到事件循环里面
    loop.run_until_complete(tasks)

    for t in task_list:
        print(t.result())
    loop.close()

6、执行多个任务按照返回的顺序获取返回值

import asyncio

async def hello(name):
    print('Hello Start' + str(name))
    await asyncio.sleep(1)
    print('Hello End' + str(name))
    return 'done', name

async def main():
    task_list = []
    for i in range(20):
        task_list.append(asyncio.ensure_future(hello('li' + str(i))))

    for res in asyncio.as_completed(task_list):
        result = await res
        print(result)

if __name__ == '__main__':
    # 获取事件循环的对象
    loop = asyncio.get_event_loop()

    # 增加处理函数到事件循环里面
    loop.run_until_complete(main())

    loop.close()

7、asyncio使用协程进行http访问

import asyncio

async def get_url():
    reader, writer = await asyncio.open_connection('www.baidu.com', 80)
    writer.write(b'GET / HTTP/1.1\r\nHOST:www.baidu.com\r\nConnection:close\r\n\r\n')
    all_lines = []
    async for line in reader:
        data = line.decode()
        all_lines.append(data)
    html = '\n'.join(all_lines)
    return html

async def main():
    tasks = []
    for url in range(20):
        tasks.append(asyncio.ensure_future(get_url()))
    for res in asyncio.as_completed(tasks):
        result = await res
        print(result)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())  # 处理单个任务
    loop.run_until_complete(asyncio.wait([main(), ]))  # 处理多个任务

    task = loop.create_task(main())  # 使用create_task返回值
    loop.run_until_complete(task)  # 处理单个任务
    loop.run_until_complete(asyncio.wait([task, ]))  # 处理多个任务

 

posted @ 2020-10-22 12:47  小粉优化大师  阅读(174)  评论(0编辑  收藏  举报