亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

__await__ 的精確規范

__await__ 的精確規范

ABOUTYOU 2023-08-22 15:01:45
Python語言參考指定object.__await__如下:object.__await__(self)必須返回一個迭代器。應該用于實現可等待的對象。例如,asyncio.Future實現此方法以與await 表達式兼容。就是這樣。我發現這個規范非常模糊而且不是很具體(諷刺的是)。好的,它應該返回一個迭代器,但是它可以是任意迭代器嗎?很明顯不是:import asyncioclass Spam:? ? def __await__(self):? ? ? ? yield from range(10)async def main():? ? await Spam()asyncio.run(main())RuntimeError: Task got bad yield: 0我假設asyncio事件循環期望迭代器生成特定類型的對象。那么它到底應該產生什么?(為什么沒有記錄下來?)編輯:據我所知,這在任何地方都沒有記錄。asyncio但我一直在自己調查,我認為理解期望其協程產生什么對象的關鍵task_step_impl在于_asynciomodule.c.更新:我已經向 cpython 存儲庫發出了 PR,目的是澄清這一點: “澄清”的模糊規范object.__await__。PR 現已合并,并且應該可以在 Python 3.10+ 的文檔中找到。
查看完整描述

2 回答

?
溫溫醬

TA貢獻1752條經驗 獲得超4個贊

語言并不關心您返回哪個迭代器。該錯誤來自asyncio,該庫對迭代器必須生成的值類型有特定的想法。Asyncio 需要__await__生成 asyncio future(包括其子類型,例如任務)或None.?其他庫,如 curio 和 trio,將期望不同類型的值??偟膩碚f,異步庫不會記錄他們的期望,__await__因為他們認為這是一個實現細節。

就 asyncio 而言,除了協程之外,您還應該使用更高級別的構造,例如 future 和任務,并等待它們。很少需要__await__手動實現,即使這樣,您也應該使用它來委托另一個可等待的信號。編寫一個__await__創建并產生自己的新掛起值的方法需要將其與事件循環結合起來并了解其內部結構。

您可以將其視為__await__編寫類似于 asyncio 的庫的工具。如果您是此類庫的作者,則當前規范就足夠了,因為您可以從迭代器中生成任何您喜歡的內容,只有事件循環中的代碼才會觀察生成的值。如果您不處于這個位置,您可能不需要實施__await__.


查看完整回答
反對 回復 2023-08-22
?
一只萌萌小番薯

TA貢獻1795條經驗 獲得超7個贊

任務只能等待其他任務/未來。來自CPython 源代碼:

? ?/* Check if `result` is FutureObj or TaskObj (and not a subclass) */

? ? /* ... */


? ? /* Check if `result` is None */

? ? /* ... error */


? ? /* Check if `result` is a Future-compatible object */

? ? /* ... */


? ? /* Check if `result` is a generator */

? ? /* ... */


? ? /* The `result` is none of the above */

? ? o = task_set_error_soon(

? ? ? ? task, PyExc_RuntimeError, "Task got bad yield: %R", result);

? ? Py_DECREF(result);

? ? return o;

編輯:如果我理解正確的話,此限制僅施加于任務,并且正常的 future 可以等待從 返回的任何可迭代對象__await__,盡管重點可能是返回的可迭代對象產生事件循環,然后最終返回結果。



查看完整回答
反對 回復 2023-08-22
  • 2 回答
  • 0 關注
  • 1642 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號