我正在尝试自学 Python 的异步功能。为此,我构建了一个异步网络抓取工具。我想限制我一次打开的连接总数,以成为服务器上的好公民。我知道信号量是一个很好的解决方案,并且 asyncio 库有一个内置的 信号量 类。我的问题是 Python 在使用 yield from
时会抱怨 async
功能,因为你正在组合 yield
和 await
语法。以下是我正在使用的确切语法……
import asyncio
import aiohttp
sema = asyncio.BoundedSemaphore(5)
async def get_page_text(url):
with (yield from sema):
try:
resp = await aiohttp.request('GET', url)
if resp.status == 200:
ret_val = await resp.text()
except:
raise ValueError
finally:
await resp.release()
return ret_val
引发此异常:
File "<ipython-input-3-9b9bdb963407>", line 14
with (yield from sema):
^
SyntaxError: 'yield from' inside async function
我能想到的一些可能的解决方案……
- 只需使用
@asyncio.coroutine
装饰器 - 使用threading.Semaphore?这似乎可能会导致其他问题
- 出于 这个 原因,请在 Python 3.6 的测试版中尝试这个。
我对 Python 的异步功能还很陌生,所以我可能会遗漏一些明显的东西。
原文由 Bruce Pucci 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以使用
async with
语句来获取异步上下文管理器:取自 此处 的示例。该页面也是
asyncio
和aiohttp
的入门读物。