gpt4 book ai didi

python - 这怎么是协程?

转载 作者:太空狗 更新时间:2023-10-30 00:29:14 25 4
gpt4 key购买 nike

我正在尝试理解 Python 中的协程(以及一般意义上的协程)。一直在阅读理论、概念和一些示例,但我仍在苦苦挣扎。我了解异步模型(做了一些 Twisted)但还不了解协程。

一个tutorial将此作为协程示例(我做了一些更改来说明我的问题):

async def download_coroutine(url, number):
"""
A coroutine to download the specified url
"""
request = urllib.request.urlopen(url)
filename = os.path.basename(url)
print("Downloading %s" % url)

with open(filename, 'wb') as file_handle:
while True:
print(number) # prints numbers to view progress
chunk = request.read(1024)
if not chunk:
print("Finished")
break
file_handle.write(chunk)
msg = 'Finished downloading {filename}'.format(filename=filename)
return msg

这是用这个运行的

coroutines = [download_coroutine(url, number) for number, url in enumerate(urls)]
completed, pending = await asyncio.wait(coroutines)

查看生成器协程示例,我可以看到一些 yield 语句。这里什么都没有,urllib 是同步的,AFAIK。

此外,由于代码应该是异步的,我希望看到一系列交错的数字。 (1, 4, 5, 1, 2, ..., "完成", ...) 。我看到的是一个重复的数字,以 Finished 结尾,然后是另一个 (3, 3, 3, 3, ... "Finished", 1, 1, 1, 1, . ..,“完成”...)。

在这一点上,我很想说教程是错误的,这是一个协程,只是因为前面有异步。

最佳答案

coroutine 中的co 代表cooperative。让步(对其他例程)使例程成为协同例程,真的,因为只有在等待时让步才能交错其他协同例程。在新async Python 3.5 及更高版本的世界,通常由 await 实现-ing 来自其他协程的结果。

根据该定义,您找到的代码不是协程。就 Python 而言,它是一个协程 对象,因为这是赋予使用 async def 创建的函数对象的类型。 .

所以是的,教程是..无用的,因为它们在协程函数中使用了完全同步的、不合作的代码。

而不是 urllib ,则需要一个异步 HTTP 库。喜欢 aiohttp :

import aiohttp

async def download_coroutine(url):
"""
A coroutine to download the specified url
"""
filename = os.path.basename(url)
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
with open(filename, 'wb') as fd:
while True:
chunk = await resp.content.read(1024)
if not chunk:
break
fd.write(chunk)
msg = 'Finished downloading {filename}'.format(filename=filename)
return msg

在等待建立连接、等待更多网络数据以及再次关闭 session 时,此协程可以让步给其他例程。

我们可以进一步使文件写入异步,但是has portability issues ; aiofiles project库使用线程来卸载阻塞调用。使用该库,代码需要更新为:

import aiofiles

async with aiofiles.open(filename, 'wb') as fd:
while True:
chunk = await resp.content.read(1024)
if not chunk:
break
await fd.write(chunk)

注意:博文已更新以解决这些问题。

关于python - 这怎么是协程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39792323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com