對於Python中可被await物件的一點研究
可被Await的4種物件
Python3.5中新增加了關於async和await語法和定義了何為Coroutines物件,在平時使用時,會分不清哪些能夠await,所以記錄下對於可被await的物件的理解.
根據PEP 492,可被await的物件主要分為4類:
- Anative coroutineobject returned from anative coroutine function.
- Agenerator-based coroutineobject returned from a function decorated withtypes.coroutine().
- An object with an__await__
- Objects defined with CPython C API with atp_as_async.am_awaitfunction, returning aniterator(similar to__await__method).
對於以上的4種物件,我將就自己的理解進行下列解釋,如有不同的意見歡迎指點.
1. Async定義的函式
在PEP 492中,同時也定義了async語法,主要用於在函式定義時,使該函式變為一個native coroutine function,也就是在用到async定義的函式時,一樣能被await
async def func(): pass async def main(): await func()
2. 裝飾器types.coroutine()修飾的函式
但是不僅僅使用types.coroutine裝飾器,函式必須使用yield from,並且後面返回一個Coroutine物件(即文中提到的除此之外的其他3種物件)
import types import asyncio from tornado.queues import Queue q = Queue() @types.coroutine def run(): print("This is run") yield from q.put(1) async def main(): await run() loop = asyncio.get_event_loop() loop.run_until_complete(main())
3. 有__await__方法的物件
顧名思義,就是定義了__await__方法的物件也能被await,同時該方法必須返回iterator,否則就會報錯
關於asyncio.future物件可被await,也是添加了__await__ = __iter__這一行
對於該類物件不是很好確定,通常可看原始碼來確定是否具有__await__方法
4. CPython中定義tp_as_async.am_await
還未嘗試過編譯CPython,所以對於這點並不是特別清楚,但是文件中也說了和__await__方法類似,同樣要返回一個iterator
補充延伸:
最初想要搞清楚可被await的物件是因為在學習tornado過程中,要不斷的使用async和await方法,為了在使用時能較清楚的明白使用條件,才去研究了await的使用條件.
而在tornado中,除了以上4點之外,我目前還了解能被await的物件或方法具有一個特徵: 那就是他們都返回Awaitable或Future,比如說tornado.queues中的Queue,在使用過程中,會發現queue中有的方法可以被await,有的方法並不可以,在查看了原始碼之後,發現可被await的方法都是返回一個Future物件,而該物件是來自於asyncio的Future,其中實現了__await__,所以才能被await.
參考文獻:<PEP 492>