python3 async語法小結
阿新 • • 發佈:2019-01-23
format 整理 gif python cio func display coroutine ()
學習了三篇關於異步IO的文章:
(1) http://python.jobbole.com/87310/
(2) http://python.jobbole.com/87541/
(3) http://python.jobbole.com/88427/
整理一下學習心得:
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)View Code9 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())) 1718 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‘)
未完待續。。。
python3 async語法小結