【发布时间】:2016-11-28 03:34:02
【问题描述】:
我正在尝试自学 Python 的异步功能。为此,我构建了一个异步网络爬虫。我想限制我一次打开的连接总数,以便成为服务器上的好公民。我知道信号量是一个很好的解决方案,并且 asyncio 库内置了一个 semaphore 类。我的问题是 Python 在 async 函数中使用 yield from 时会抱怨,因为您正在组合 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装饰器 - 使用线程。信号量?这似乎可能会导致其他问题
- 出于this 原因,在 Python 3.6 的 Beta 版中尝试此操作。
我对 Python 的异步功能非常陌生,所以我可能会遗漏一些明显的东西。
【问题讨论】:
-
python3.7 不允许将
yield from与关键字async一起使用。yield,yield from是和装饰器一起使用的@asyncio.coroutine -
BoundedSemaphore(5) 是否意味着您每秒只发出 5 个请求?或者是如何工作的?
标签: python semaphore python-3.5 python-asyncio python-3.6