欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python3 async语法小结

程序员文章站 2022-12-17 07:54:44
学习了三篇关于异步IO的文章: (1) http://python.jobbole.com/87310/ (2) http://python.jobbole.com/87541/ (3) http://python.jobbole.com/88427/整理一下学习心得: 1 # _*_ coding ......

学习了三篇关于异步io的文章:

  (1) http://python.jobbole.com/87310/
  (2) http://python.jobbole.com/87541/
  (3) http://python.jobbole.com/88427/
整理一下学习心得:

python3 async语法小结
  1 # _*_ coding: utf-8 _*_
  2 import asyncio
  3 import functools
  4 
  5 
  6 async def do_some_work(x):
  7     print("\033[;31mwaiting {}s\033[0m".format(str(x)))
  8     await asyncio.sleep(x)
  9     print("\033[;32msleep {}s done...\033[0m".format(str(x)))
 10     return 'done after {}s'.format(x)
 11 
 12 
 13 def callback(future):
 14     # 协程回调函数,需要 future 对象作为回调函数的最后一个参数。
 15     # 通过future.result()可以获取协程执行的结果。
 16     print("\033[;36mwaiting time {} ...\033[0m".format(future.result()))
 17 
 18 
 19 def done_callback(loop, future):
 20     # 协程回调函数
 21     print("\033[;36mwaiting time {} ...\033[0m".format(future.result()))
 22     loop.stop()  # add this line for run_forever_func
 23 
 24 
 25 def run_until_complete_func():
 26     futu1 = asyncio.ensure_future(do_some_work(3))  # 将协程函数包装成 future 对象
 27     futu1.add_done_callback(callback)  # 为这个 future 对象添加回调函数,当协程函数运行完后会调用回调函数。
 28     # add_done_callback只能接受一个回调函数作为参数,如果回调函数有参数,可以使用偏函数预处理回调函数。
 29 
 30     futu2 = asyncio.ensure_future(do_some_work(1))
 31     futu2.add_done_callback(callback)
 32 
 33     futus = [futu1, futu2]
 34     loop = asyncio.get_event_loop()
 35     # run_until_complete只接受单个 coroutine 或 future 对象作为参数;
 36     # 但可以使用 asyncio.gather(*futures) 把多个future聚合包装成单个future;
 37     # 也可以使用 asyncio.wait(futures),asyncio.wait() 方法接受一个task列表。
 38     loop.run_until_complete(asyncio.gather(*futus))  # 或者:loop.run_until_complete(asyncio.wait(futus))
 39     loop.close()
 40 
 41 
 42 def run_forever_func():
 43     loop = asyncio.get_event_loop()
 44 
 45     futu1 = asyncio.ensure_future(do_some_work(1))
 46     futu2 = asyncio.ensure_future(do_some_work(3))
 47     futus = asyncio.gather(futu1, futu2)  # 将两个 future 对象聚合成一个 future 对象
 48     futus.add_done_callback(functools.partial(done_callback, loop))  # 为聚合后的新 future 对象添加回调函数
 49 
 50     loop.run_forever()
 51     loop.close()
 52 
 53 
 54 async def coroutine_return(start_func):
 55     coroutine1 = do_some_work(5)
 56     coroutine2 = do_some_work(10)
 57     coroutine3 = do_some_work(10)
 58     tasks = [
 59         asyncio.ensure_future(coroutine1),
 60         asyncio.ensure_future(coroutine2),
 61         asyncio.ensure_future(coroutine3)
 62     ]
 63     if start_func == 'wait':
 64         return await asyncio.wait(tasks)
 65     elif start_func == 'gather':
 66         return await asyncio.gather(*tasks)
 67     elif start_func == 'as_completed':
 68         coroutine_results = []
 69         for task in asyncio.as_completed(tasks):
 70             result = await task  # 获取协程函数的返回值
 71             coroutine_results.append(result)
 72         return coroutine_results
 73 
 74 # 【聚合后的协程函数的返回值】
 75 # (1) 如果使用asyncio.gather创建协程对象,那么使用await挂起的有阻塞的协程,它们的返回值就是协程运行的结果。
 76 # (2) 如果使用asyncio.wait创建协程对象,那么使用await挂起的有阻塞的协程,它们的返回值是一个两个元素的元组,
 77 # 元组第一个元素是finished状态的所有协程对象的集合,第二个元素目前来看是一个空的集合。
 78 # (3) 还可以使用asyncio.as_completed创建协程对象,但是这个方法和以上两个方法略有不同,
 79 # 这个方法返回一个生成器,生成器的元素是单个协程对象,然后再通过循环并使用await启动各个协程函数。
 80 # (4) run_until_complete函数可以理解为仅仅是驱动event_loop,而不会影响作为它参数的协程对象。
 81 # 即它的返回值就是作为它参数的协程函数的返回值。
 82 # (5) 当所有的协程对象都是finished状态时,才会返回。
 83 
 84 
 85 def coroutine_return_done(start_func):
 86     loop = asyncio.get_event_loop()
 87     if start_func == 'wait':
 88         result, pending = loop.run_until_complete(coroutine_return(start_func))
 89     elif start_func == 'gather':
 90         result = loop.run_until_complete(coroutine_return(start_func))
 91     elif start_func == 'as_completed':
 92         result = loop.run_until_complete(coroutine_return(start_func))
 93     else:
 94         result = 'coroutine not start...'
 95     print(result)
 96 
 97 
 98 if __name__ == '__main__':
 99     run_until_complete_func()
100     # run_forever_func()
101     # coroutine_return_done('as_completed')
view code

 

未完待续。。。