摘要:本文翻譯自Coroutines and Tasks,主要介紹asyncio中用於處理協程和任務的方法和接口。在翻譯過程當中,譯者在官方文檔的基礎上增長了部分樣例代碼和示意圖表,以幫助讀者對文檔的理解。本文內容主要針對python3.7,在低版本的python中可能不適用,敬請留意。原創內容,如需轉載請註明出處。
譯者:馬鳴謙(郵箱:1612557569@qq.com)html
協程(coroutines)是經過async/await
定義函數或方法,是使用asyncio進行異步編程的首選途徑。以下,是一個協程的例子:python
import asyncio async def main(): print("hello") await asyncio.sleep(1) print("world")
上例中的 main
方法就是咱們定義的協程
。
咱們在交互環境(Python3.7)下執行以上代碼,看看效果:shell
>>> import asyncio >>> async def main(): ... print("hello") ... await asyncio.sleep(1) ... print("world") >>> asyncio.run(main()) hello world
須要注意的是:若是像執行普通代碼同樣直接調用main()
,只會返回一個coroutine
對象,main()
方法內的代碼不會執行:編程
>>> main() #直接執行`main()`返回的是一個`coroutine對象`。 <coroutine object main at 0x0000000002C97848>
實際上,asyncio提供了三種執行協程
的機制:安全
asyncio.run()
執行協程。通常用於執行最頂層的入口函數,如main()
。await
一個協程
。通常用於在一個協程
中調用另外一協程
。 以下是一個示例:>>> import time >>> async def say_after(delay,what): await asyncio.sleep(delay) print(what) >>> async def main(): print(f"started at {time.strftime('%X')}") await say_after(1,"hello") await say_after(2,"world") print(f"finished at {time.strftime('%X')}") >>> asyncio.run(main()) started at 16:47:10 hello world finished at 16:47:13
執行耗時 3秒bash
asyncio.create_task()
方法將Coroutine(協程)
封裝爲Task(任務)
。通常用於實現異步併發操做。 須要注意的是,只有在當前線程存在事件循環的時候才能建立任務(Task)。咱們修改以上的例程,併發執行 兩個say_after
協程。多線程
async def main(): task1 = asyncio.create_task(say_after(1,"hello")) task2 = asyncio.create_task(say_after(2,"world")) print(f"started at {time.strftime('%X')}") await task1 await task2 print(f"finished at {time.strftime('%X')}")
執行asyncio.run(main())
,結果以下:併發
started at 17:01:34 hello world finished at 17:01:36
耗時2秒less
若是一個對象可以被用在await
表達式中,那麼咱們稱這個對象是可等待對象(awaitable object)
。不少asyncio API
都被設計成了可等待的
。
主要有三類可等待對象:異步
coroutine
Task
Future
。Python的協程
是可等待的(awaitable)
,所以可以被其餘協程
用在await
表達式中。
import asyncio async def nested(): print("something") async def main(): # 若是直接調用 "nested()",什麼都不會發生. # 直接調用的時候只是建立了一個 協程對象 ,但這個對象沒有被 await, # 因此它並不會執行. nested() # 那麼咱們 await 這個協程,看看會是什麼結果: await nested() # 將會打印 "something". asyncio.run(main())
重要:在這篇文章中,術語coroutine
或協程
指代兩個關係緊密的概念:
協程函數(coroutine function)
:由async def
定義的函數;協程對象(coroutine object)
:調用 協程函數
返回的對象。asyncio也支持傳統的基於生成器的協程。
Task
用來 併發的 調度協程。
當一個協程
經過相似 asyncio.create_task()
的函數被封裝進一個 Task
時,這個協程
會很快被自動調度執行:
import asyncio async def nested(): return 42 async def main(): # Schedule nested() to run soon concurrently # with "main()". task = asyncio.create_task(nested()) # "task" can now be used to cancel "nested()", or # can simply be awaited to wait until it is complete: await task asyncio.run(main())
Future
是一種特殊的 底層 可等待對象,表明一個異步操做的最終結果。
當一個Future
對象被await
的時候,表示當前的協程會持續等待,直到 Future
對象所指向的異步操做執行完畢。
在asyncio中,Future
對象能使基於回調的代碼被用於asyn/await
表達式中。
通常狀況下,在應用層編程中,沒有必要 建立Future
對象。
有時候,有些Future
對象會被一些庫和asyncio API暴露出來,咱們能夠await
它們:
async def main(): await function_that_returns_a_future_object() # this is also valid: await asyncio.gather( function_that_returns_a_future_object(), some_python_coroutine() )
底層函數返回Future
對象的一個例子是:loop.run_in_executor
asyncio.run(coro, * , debug=False)
這個函數運行coro
參數指定的 協程
,負責 管理asyncio事件循環 , 終止異步生成器。
在同一個線程中,當已經有asyncio事件循環在執行時,不能調用此函數。
若是debug=True
,事件循環將運行在 調試模式。
此函數老是建立一個新的事件循環,並在最後關閉它。建議將它用做asyncio程序的主入口,而且只調用一次。
Python3.7新增
重要:這個函數是在Python3.7被臨時添加到asyncio中的。
asyncio.create_task(coro)
將coro
參數指定的協程(coroutine)
封裝到一個Task
中,並調度執行。返回值是一個Task
對象。
任務在由get_running_loop()
返回的事件循環(loop)中執行。若是當前線程中沒有正在運行的事件循環,將會引起RuntimeError
異常:
import asyncio async def coro_1(): print("do somthing") task = asyncio.create_task(coro_1())
由於當前線程中沒有正運行的事件循環,因此引起異常:
Traceback (most recent call last): File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3265, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-4-456c15a4ed16>", line 1, in <module> task = asyncio.create_task(coro_1()) File "C:\Program Files\Python37\lib\asyncio\tasks.py", line 324, in create_task loop = events.get_running_loop() RuntimeError: no running event loop
對以上代碼稍做修改,建立main()
方法,在其中建立Task
對象,而後在主程序中利用asyncio.run()
建立事件循環
:
import asyncio async def coro(): print("something is running") async def main(): task = asyncio.create_task(coro()) print(asyncio.get_running_loop()) asyncio.run(main())
執行結果以下:
<_WindowsSelectorEventLoop running=True closed=False debug=False> something is running
此函數已經被引入到Python3.7。在Python早期版本中,可使用底層函數asyncio.ensure_future()
代替。
async def coro(): ... # In Python 3.7+ task = asyncio.create_task(coro()) ... # This works in all Python versions but is less readable task = asyncio.ensure_future(coro()) ...
Python3.7新增
coroutine asyncio.sleep(delay,result=None,* ,loop=None)
阻塞delay
秒,例如delay=3
,則阻塞3秒。
若是指定了result
參數的值
,則在協程結束時,將該值
返回給調用者。
sleep()
一般只暫停當前task
,並不影響其餘task
的執行。
不建議使用loop
參數,由於Python計劃在3.10
版本中移除它。
如下是一個協程的例子,功能是在5秒鐘內,每秒顯示一次當前的日期
:
import asyncio import datetime async def display_date(): loop = asyncio.get_running_loop() end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break await asyncio.sleep(1) asyncio.run(display_date())
執行結果大體以下:
2018-11-20 11:27:15.961830 2018-11-20 11:27:16.961887 2018-11-20 11:27:17.961944 2018-11-20 11:27:18.962001 2018-11-20 11:27:19.962059 2018-11-20 11:27:20.962116
awaitable asyncio.gather(* aws, loop=None, return_exceptions=False)
併發執行aws
參數指定的 可等待(awaitable)對象
序列。
若是 aws
序列中的某個 awaitable 對象
是一個 協程
,則自動將這個 協程
封裝爲 Task
對象進行處理。例如:
import asyncio async def factorial(name, number): f = 1 for i in range(2, number + 1): print(f"Task {name}: Compute factorial({i})...") await asyncio.sleep(1) f *= i print(f"Task {name}: factorial({number}) = {f}") async def main(): # Schedule three calls *concurrently*: await asyncio.gather( factorial("A", 2), factorial("B", 3), factorial("C", 4), ) asyncio.run(main()) # Expected output: # # Task A: Compute factorial(2)... # Task B: Compute factorial(2)... # Task C: Compute factorial(2)... # Task A: factorial(2) = 2 # Task B: Compute factorial(3)... # Task C: Compute factorial(3)... # Task B: factorial(3) = 6 # Task C: Compute factorial(4)... # Task C: factorial(4) = 24
若是全部的awaitable
對象都執行完畢,則返回 awaitable對象執行結果的聚合列表。返回值的順序於aws
參數的順序一致。
簡單修改以上代碼:
import asyncio async def factorial(name, number): f = 1 for i in range(2, number + 1): #print(f"Task {name}: Compute factorial({i})...") await asyncio.sleep(1) f *= i #print(f"Task {name}: factorial({number}) = {f}") return number async def main(): # Schedule three calls *concurrently*: print(await asyncio.gather( factorial("A", 2), factorial("B", 3), factorial("C", 4), )) asyncio.run(main()) # Expected output: # #[2, 3, 4]#await asyncio.gather()的返回值是一個列表, #分別對應factorial("A", 2),factorial("B", 3),factorial("C", 4)的執行結果。
若是return_execptions
參數爲False
(默認值即爲False
),引起的第一個異常會當即傳播給等待gather()
的任務,即調用await asyncio.gather()
對象。序列中其餘awaitable
對象的執行不會受影響。例如:
import asyncio async def division(divisor, dividend): if divisor == 0: raise ZeroDivisionError else: print(f"{dividend}/{divisor}={dividend/divisor}") return dividend/divisor async def main(): # Schedule three calls *concurrently*: print(await asyncio.gather( division(0, 2), division(1, 2), division(2, 2), )) asyncio.run(main())
執行結果:
2/1=2.0 2/2=1.0 Traceback (most recent call last): File "test.py", line 19, in <module> asyncio.run(main()) File "c:\Program Files\Python37\lib\asyncio\runners.py", line 43, in run return loop.run_until_complete(main) File "c:\Program Files\Python37\lib\asyncio\base_events.py", line 573, in run_until_complete return future.result() File "test.py", line 16, in main division(2, 2), File "test.py", line 6, in division raise ZeroDivisionError ZeroDivisionError
若是return_exceptions
參數爲True
,異常會和正常結果同樣,被聚合到結果列表中返回。
對以上代碼稍做修改,將return_exceptions
設爲True
:
import asyncio async def division(divisor, dividend): if divisor == 0: raise ZeroDivisionError else: print(f"{dividend}/{divisor}={dividend/divisor}") return dividend/divisor async def main(): # Schedule three calls *concurrently*: print(await asyncio.gather( division(0, 2), division(1, 2), division(2, 2), return_exceptions=True )) asyncio.run(main())
執行結果以下:
2/1=2.0 2/2=1.0 [ZeroDivisionError(), 2.0, 1.0]#錯誤不會向上傳播,而是做爲結果返回
若是gather()
被取消,則提交的全部awaitable
對象(還沒有執行完成的)都會被取消。例如:
import asyncio async def division(divisor, dividend): if divisor == 0: raise ZeroDivisionError else: await asyncio.sleep(divisor) print(f"{dividend}/{divisor}={dividend/divisor}") return dividend/divisor async def main(): # Schedule three calls *concurrently*: t = asyncio.gather( division(0, 2), division(1, 5), division(3, 6), return_exceptions=True ) await asyncio.sleep(2) t.cancel() await t asyncio.run(main())
執行結果:
5/1=5.0 #除已執行的以外,其餘的任務所有被取消 Traceback (most recent call last): File "test.py", line 23, in <module> asyncio.run(main()) File "c:\Program Files\Python37\lib\asyncio\runners.py", line 43, in run return loop.run_until_complete(main) File "c:\Program Files\Python37\lib\asyncio\base_events.py", line 573, in run_until_complete return future.result() concurrent.futures._base.CancelledError #在return_exceptions=True的狀況下,異常依然向上傳播。
若是aws
中某些Task
或Future
被取消,gather()
調用不會被取消,被取消的Task
或Future
會以引起CancelledError
的方式被處理。這樣能夠避免個別awaitable
對象的取消操做影響其餘awaitable
對象的執行。
例如:
import asyncio async def division(divisor, dividend): if divisor == 0: raise ZeroDivisionError else: await asyncio.sleep(divisor) print(f"{dividend}/{divisor}={dividend/divisor}") return dividend/divisor async def main(): # Schedule three calls *concurrently*: task1 = asyncio.create_task(division(0, 2)) task2 = asyncio.create_task(division(1, 5)) task3 = asyncio.create_task(division(3, 6)) t = asyncio.gather( task1, task2, task3, return_exceptions=True ) task1.cancel() print(await t) asyncio.run(main())
預期執行結果以下:
5/1=5.0 6/3=2.0 [CancelledError(), 5.0, 2.0] # 僅task1被取消,其餘任務不受影響。
awaitable asyncio.shield(aw, * , loop=None)
防止awaitable
對象被取消(cancelled)執行。
若是aw
參數是一個協程(coroutines)
,該對象會被自動封裝爲Task
對象進行處理。
一般,代碼:
#code 1 res = await shield(something())
同代碼:
#code 2 res = await something()
是等價的。
特殊狀況是,若是包含以上代碼的協程
被 取消,code 1
與code 2
的執行效果就徹底不一樣了:
code 1
中,運行於something()
中的任務 不會被取消。code 2
中,運行於something()
中的任務 會被取消。在code 1
中,從something()
的視角看,取消操做並無發生。然而,事實上它的調用者確實被取消了,因此await shield(something())
仍然會引起一個CancelledError
異常。
import asyncio import time async def division(divisor, dividend): if divisor == 0: raise ZeroDivisionError else: await asyncio.sleep(divisor) print(f"{time.strftime('%X')}:{dividend}/{divisor}={dividend/divisor}") return dividend/divisor async def main(): # Schedule three calls *concurrently*: print(f"Start time:{time.strftime('%X')}") task1 = asyncio.shield(division(1, 2)) task2 = asyncio.create_task(division(1, 5)) task3 = asyncio.create_task(division(3, 6)) res = asyncio.gather(task1, task2, task3, return_exceptions=True) task1.cancel() task2.cancel() print(await res) asyncio.run(main())
執行結果:
Start time:10:38:48 10:38:49:2/1=2.0 10:38:51:6/3=2.0 [CancelledError(), CancelledError(), 2.0] #task1雖然被取消,可是division(1,2)依然正常執行了。 #task2被取消後,division(1,5)沒有執行 #雖然task1內的協程被執行,但返回值依然爲CancelledError
若是something()
以其餘的方式被取消,好比從自身內部取消,那麼shield()
也會被取消。
若是但願徹底忽略取消操做
(不推薦這麼作),則能夠將shield()
與try/except
結合起來使用:
try: res = await shield(something()) except CancelledError: res = None
coroutine asyncio.wait_for(aw,timeout,*,loop=None)
在timeout
時間以內,等待aw
參數指定的awaitable
對象執行完畢。
若是aw
是一個協程,則會被自動做爲Task
處理。
timeout
能夠是None
也能夠是一個float
或int
類型的數字,表示須要等待的秒數。若是timeout
是None
,則永不超時,一直阻塞到aw
執行完畢。
若是達到timeout
時間,將會取消待執行的任務,引起asyncio.TimeoutError
.
若是想避免任務被取消,能夠將其封裝在shield()
中。
程序會等待到任務確實被取消掉,因此等待的總時間會比timeout
略大。
若是await_for()
被取消,aw
也會被取消。
loop
參數將在Python3.10中刪除,因此不推薦使用。
示例:
async def eternity(): # Sleep for one hour await asyncio.sleep(3600) print('yay!') async def main(): # Wait for at most 1 second try: await asyncio.wait_for(eternity(), timeout=1.0) except asyncio.TimeoutError: print('timeout!') asyncio.run(main()) # Expected output: # # timeout!
Python3.7新特性:當aw
由於超時被取消,wait_for()
等到aw
確實被取消以後返回異常。在之前的版本中,wait_for
會當即返回異常。
coroutine asyncio.wait(aws,*,loop=None,timeout=None,return_when=ALL_COMPLETED)
併發執行aws
中的awaitable
對象,一直阻塞到return_when
指定的狀況出現。
若是aws
中的某些對象是協程(coroutine)
,則自動轉換爲Task
對象進行處理。直接將coroutine
對象傳遞給wait()
會致使使人迷惑的執行結果,因此不建議這麼作。
返回值是兩個Task/Future
集合:(done,pending
)。
用法示例:
done,pending = await asyncio.wait(aws)
loop
參數將在Python3.10中刪除,因此不建議使用。
timeout
參數能夠是一個int
或float
類型的值,能夠控制最大等待時間。
須要注意的是,wait()
不會引起asyncio.TimeoutError
錯誤。返回前沒有被執行的Future
和Task
會被簡單的放入pending
集合。
return_when
決定函數返回的時機。它只能被設置爲如下常量:
|Constant|Description|
|-|-|
|FIRST_COMPLETED|The function will return when any future finishes or is cancelled.|
|FIRST_EXCEPTION|The function will return when any future finishes by raising an exception. If no future raises an exception then it is equivalent to ALL_COMPLETED.|
|ALL_COMPLETED|The function will return when all futures finish or are cancelled.|
與wait_for()
不一樣,wait()
不會再超時的時候取消任務。
注意:
由於wait()
會自動將協程
轉換爲Task對象
進行處理,而後返回這些隱式建立的Task
到(done,pending)集合,因此如下代碼不會如預期的那樣執行。
async def foo(): return 42 coro = foo() done, pending = await asyncio.wait({coro}) if coro in done: # 由於wait()會自動將協程轉換爲Task對象進行處理,而後返回這些隱式建立的Task到(done,pending)集合,因此這個條件分支永遠不會被執行。
上面的代碼能夠作以下修正:
async def foo(): return 42 task = asyncio.create_task(foo()) done, pending = await asyncio.wait({task}) if task in done: # 這回能夠正常執行了.
因此,正如上文所講,不建議將coroutine
對象直接傳遞給wait()
。
asyncio.as_completed(aws,*,loop=None,timeout=None)
併發執行aws
中的awaitable
對象。返回一個Future
對象迭代器。每次迭代時返回的Future
對象表明待執行的awaitable
對象集合裏最先出現的結果。注意:迭代器返回的順序與aws
列表的順序無關,只與結果出現的遲早有關。
若是超時以前還有Future
對象未完成,則引起asyncio.TimeoutError
異常。
用法示例:
for f in as_completed(aws): earliest_result = await f # ...
如下爲一個完整的例子:
import asyncio import time async def eternity(delay): await asyncio.sleep(delay) print(f"delay for {delay} seconds.") return delay async def main(): print(f"Start at: {time.strftime('%X')}") tasks = [eternity(i) for i in range(10)] for f in asyncio.as_completed(tasks): res = await f print(f"End at: {time.strftime('%X')}") asyncio.run(main())
執行結果以下:
Start at: 17:19:11 delay for 0 seconds. delay for 1 seconds. delay for 2 seconds. delay for 3 seconds. delay for 4 seconds. delay for 5 seconds. delay for 6 seconds. delay for 7 seconds. delay for 8 seconds. delay for 9 seconds. End at: 17:19:20
asyncio.run_coroutine_threadsafe(coro,loop)
向loop
指定的事件循環提交一個由coro
指定協程。線程安全。
返回一個concurrent.futures.Future
對象,等待另外一個線程返回結果。
這個函數用於從當前線程
向運行事件循環的線程
提交協程(coroutine)
。
例如:
# Create a coroutine coro = asyncio.sleep(1, result=3) # Submit the coroutine to a given loop future = asyncio.run_coroutine_threadsafe(coro, loop) # Wait for the result with an optional timeout argument assert future.result(timeout) == 3
若是協程
出現異常,返回的Future
會收到通知。返回的Future
也能夠被用做取消事件循環中的任務:
try: result = future.result(timeout) except asyncio.TimeoutError: print('The coroutine took too long, cancelling the task...') future.cancel() except Exception as exc: print(f'The coroutine raised an exception: {exc!r}') else: print(f'The coroutine returned: {result!r}')
能夠參考併發與多線程章節。
與其餘asyncio函數不一樣,該函數須要 顯式 傳遞loop
參數。
新增於Python 3.5.1
asyncio.current_task(loop=None)
返回事件循環中正在運行的Task
實例,若是沒有Task
在執行,則返回None
。
若是loop
爲None
,則使用get_running_loop()
獲取當前事件循環。
新增於Python3.7
asyncio.all_tasks(loop=None)
返回事件循環中還沒有運行結束的Task
對象集合。
若是loop
爲None
,則,使用get_running_loop()
獲取當前事件循環。
新增於Python3.7
class asyncio.Task(coro,*,loop=None)
相似與Future
對象,用於執行Python協程。非線程安全。
Tasks
用於在事件循環
中執行協程
。若是協程
等待一個Future
,那麼Task
會暫停協程
的執行,直到Future
執行完成。當Future
完成時,協程
的執行會恢復。
事件循環的 協做調度 模式:一個事件循環同一時間只執行一個Task
。當這個Task
等待某個Future
返回時,事件循環執行其餘的Task
、回調
或IO操做
。
能夠經過高層函數asyncio.create_task()
建立Task
,或者經過底層函數loop.create_task()
和ensure_future()
建立Task
。可是不建議直接實例化Task
對象。
若是想要取消一個Task
的執行,可使用cancel()
方法。調用cancel()
會引發Task
對象向被封裝的協程
拋出CancelledError
異常。當取消行爲發生時,若是協程
正在等待某個Future
對象執行,該Future
對象將被取消。
cancelled()
方法用於檢查某個Task
是否已被取消。若是Task
封裝的協程
沒有阻止CancelledError
異常,且Task
確實被取消了,則該方法返回True
。
asyncio.Task
繼承了Future
類中除Future.set_result()
和Future.set_exception()
之外的全部方法。
Task
對象支持contextvars
模塊:當一個Task
被建立的時候,它會複製當前的上下文,而後在複製的上下文副本中執行協程。
Python3.7中的變動:添加了對contextvars
模塊的支持。
申請取消任務。
將在下一個事件循環週期中將CancelledError
異常拋給封裝在Task
中的協程。
收到CancelledError
異常後,協程
有機會處理異常,甚至以try ...except CancelledError ...finally
來拒絕請求。所以,與Future.cancel()
不一樣,Task.cancel()
不能保證Task
必定被取消掉。固然,拒絕取消請求這種操做並不常見,並且很不提倡。
如下例子能夠說明協程如何攔截取消請求:
import asyncio async def cancel_me(): print('cancel_me(): before sleep') try: # Wait for 1 hour await asyncio.sleep(3600) except asyncio.CancelledError: print('cancel_me(): cancel sleep') raise finally: print('cancel_me(): after sleep') async def main(): # Create a "cancel_me" Task task = asyncio.create_task(cancel_me()) # Wait for 1 second await asyncio.sleep(1) task.cancel() try: await task except asyncio.CancelledError: print("main(): cancel_me is cancelled now") asyncio.run(main()) # Expected output: # # cancel_me(): before sleep # cancel_me(): cancel sleep # cancel_me(): after sleep # main(): cancel_me is cancelled now
若是Task
已經被取消,則返回True
。
當取消請求經過cancel()
被提交,且Task
封裝的協程
傳播了拋給它的CancelledError
異常,則此Task
被取消。
若是Task
已完成,則返回True
。
Task
完成有三種狀況:
Task
被取消返回Task
的執行結果。
若是Task
已經完成,則返回Task
封裝的協程的執行結果(若是Task
封裝的協程引起異常,則從新引起該異常)。
若是Task
已經取消,則該方法引起CancelledError
異常。
若是Task
的結果還不可用,該方法引起InvalidStateError
異常。
返回Task
的異常。
若是封裝的協程引起了異常,則返回此異常。若是封裝的協程執行正常,則返回None
。
若是Task
已被取消,則引起CancelledError
異常。
若是Task
還沒有完成,則引起InvalidStateError
異常。
添加一個回調函數,在Task
完成後執行。
這個方法只應用在基於回調的底層編程中。
具體細節能夠參考Future.remove_done_callback()
返回此Task
的堆棧幀列表。
幀的順序老是 由舊到新。
暫停中的協程只返回一個堆棧幀。
可選參數limit
用於限定返回幀的最大數目。默認狀況下,全部有效的幀都會返回。
在返回堆棧和返回異常回溯時,列表的順序會有所不一樣:
打印Task
的棧幀或異常回溯。
此方法用於輸出由get_stack()
取回的幀列表,輸出形式相似於回溯(traceback)模塊
limit
參數會直接傳遞給get_stack()
。
file
參數指定輸出的I/O流,默認爲sys.stderr
。
返回一個事件循環上全部任務的集合。
默認狀況下,當前事件循環上全部的任務都會被返回。若是loop
參數爲'None',則經過get_event_loop()
方法獲取當前事件循環。
此方法將在Python3.9中被移除,因此不建議使用。可使用asyncio.all_tasks()
代替。
返回當前正在運行的Task
或None
。
若是loop
參數爲'None',則經過get_event_loop()
方法獲取當前事件循環。
此方法將在Python3.9中被移除,因此不建議使用。可使用asyncio.current_task()
代替。
提示:對基於生成器的協程的支持將在Python3.10中移除,不建議使用。
基於生成器的協程是早期的異步實現方式,出如今async/await
語法以前,使用yield from
表達式等待Future
或其餘協程。
基於生成器的協程應該用@asyncio.coroutine
來修飾,儘管這不是強制的。
基於生成器的協程的修飾器。
這個修飾器能使傳統的基於生成器的協程
與async/await
語法兼容:
@asyncio.coroutine def old_style_coroutine(): yield from asyncio.sleep(1) async def main(): await old_style_coroutine()
此修飾器將在Python3.10中被移除,因此不建議再使用。
此修飾器不能用於async def
的協程中。
若是obj
對象是一個coroutine
對象,則返回True
。
此方法與inspect.iscoroutine()
不一樣,由於它對基於生成器的協程也返回True
。
若是func
是一個coroutine
方法,則返回True
。
此方法inspect.iscoroutinefunction()
不一樣,由於它對用@coroutine
修飾的基於生成器的協程也返回True
。