"await"关键字是如何工作的?

4
对于下面的协程(f),
import csv
import urllib

def f(resp):
   print('Line 1')
   yield csv.reader(resp.read().decode('utf-8'))


def h():
    url = 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NYSE&render=download'    
    resp = urllib.urlopen(url)
    cr = f(resp)
cr = f(resp) 将一个迭代器对象赋值给 crcr.next() 执行第一行并在 yield 关键字处阻塞。
我的理解是,使用语法 cr=f(resp) 时,在幕后没有事件循环(任务调度程序)和线程。
如果相同的函数 (h) 中有以下提到的 await f(resp)await 关键字要求使用 async 语法),而不是说 cr=f(resp)(如上所述),
async def h_async():
    url = 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NYSE&render=download'    
    resp = urllib.urlopen(url)
    await f(resp)

然后,

await f(resp)cr=f(resp) 有什么不同?

h_async()h() 有什么不同?await关键字是否在后台引入了事件循环(任务调度程序)和线程,就像这个示例代码所示。


1
这里可以找到一篇长文:https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/ - Caramiriel
@Caramiriel 我在提出这个问题之前已经阅读过这篇文章。但是作者混淆了asyncio包。 - overexchange
1
await 可以用于任何协程/任务/未来对象,因此在协程方面并没有太大的区别(异步方法实际上是协程,参见:https://repl.it/repls/OrchidWarmheartedLinks)。异步/等待的威力在于任务中,其中方法可以在后台线程中调度,从而可以并发运行。想象一下启动下载,在此期间进行一些计算,并在实际需要数据时 await 数据。我会留下一个完整的答案给那些能更好地解释它的人,因为这个材料对我来说也是相当新的。 - Caramiriel
1个回答

1

await EXPR 表示事件任务调度器可以在此步骤上切换到其他内容(例如,从任务队列中拉取准备好的内容),并且表示 EXPR 是可等待的。如果 EXPR 是一个协程,那么它可以在内部具有后续 await,当该协程处于非阻塞等待状态时(如 I/O 或网络响应、休眠等),也可以执行其他操作。


2
使用语法cr = f(resp),事件任务调度程序是否在幕后工作? - overexchange

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接