You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中await用户自定义类实例的执行机制是什么?

Python中await关键字的深入解析

Python官方文档指出:

await是Python的关键字,通常有两种使用方式:

await task
await coroutine

await的行为很大程度上取决于被等待对象的类型。

在相关章节中提到:

  1. “coroutine(协程)”与“coroutine object(协程对象)”是同义词。
  2. “coroutine object(协程对象)”由调用“coroutine function(协程函数)”(也称为“asynchronous function(异步函数)”,二者为同义词)创建。

示例如下:

async def loudmouth_penguin(magic_number: int):
    print(
     "I am a super special talking penguin. Far cooler than that printer. "
     f"By the way, my lucky number is: {magic_number}."
    )
obj = loudmouth_penguin(magic_number=3)

在此示例中,loudmouth_penguin是“协程函数”(或“异步函数”),obj是“协程对象”(或“协程”)。

Task(任务)可通过asyncio.create_task函数创建:

task = asyncio.create_task(coroutine)

回到await的行为:

  • await一个task会将当前task或协程的控制权交还给事件循环
  • 与task不同,await一个协程不会将控制权交还给事件循环!await coroutine的行为实际上与调用普通同步Python函数相同。

接下来是一个示例(添加了更多打印语句来观察执行过程):

class Rock:
    def __await__(self):
        print(f"\t\tRock.__await__ called")
        value_sent_in = yield 7
        print(f"\t\tRock.__await__ resuming with value: {value_sent_in}.")
        return value_sent_in

async def main():
    print(f"\tBeginning coroutine main().")
    rock = Rock()
    print(f"\tAwaiting rock...")
    value_from_rock = await rock
    print(f"\tCoroutine received value: {value_from_rock} from rock.")
    return 23

print(f"Calling coroutine")
coroutine = main()
intermediate_result = coroutine.send(None)
print(f"Coroutine paused and returned intermediate value: {intermediate_result}.\n")

print(f"Resuming coroutine and sending in value: 42.")
try:
    coroutine.send(42)
except StopIteration as e:
    returned_value = e.value
print(f"Coroutine main() finished and provided value: {returned_value}.")

运行结果如下:

Calling coroutine
    Beginning coroutine main().
    Awaiting rock...
        Rock.__await__ called
Coroutine paused and returned intermediate value: 7.

Resuming coroutine and sending in value: 42.
        Rock.__await__ resuming with value: 42.
    Coroutine received value: 42 from rock.
Coroutine main() finished and provided value: 23.

在此示例中,我们使用await的方式是官方文档未提及的:等待一个用户自定义类的实例(即value_from_rock = await rock这行代码)。

当我们await用户自定义类的实例时,会发生什么?官方文档未说明,只能自行推测。

推测其行为是:立即调用该类的__await__成员函数(不会将控制权交还给事件循环)并返回结果?

也就是说:

value_from_rock = await rock

实际上等同于:

value_from_rock = rock.__await__()
yield value_from_rock 

?

注意:在执行value_from_rock = await rock之后,下一行代码:

print(f"\tCoroutine received value: {value_from_rock} from rock.")

在首次调用协程时并未执行,看起来像是立即返回了。


内容的提问来源于stack exchange,提问作者robertspierre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.09 05:13:09