Bru*_*cci 6 python semaphore python-asyncio python-3.5 python-3.6
我正在尝试自学Python的异步功能.为此,我构建了一个异步Web scraper.我想限制我一次打开的连接总数,以成为服务器上的好公民.我知道信号量是一个很好的解决方案,并且asyncio库内置了一个信号量类.我的问题是,当你在组合和语法yield from中使用async函数时,Python会抱怨.以下是我正在使用的确切语法...yieldawait
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
Run Code Online (Sandbox Code Playgroud)
提出这个例外:
File "<ipython-input-3-9b9bdb963407>", line 14
with (yield from sema):
^
SyntaxError: 'yield from' inside async function
Run Code Online (Sandbox Code Playgroud)
我能想到的一些可能的解决方案......
@asyncio.coroutine装饰器我是Python的异步功能的新手,所以我可能会遗漏一些明显的东西.
Seb*_*zny 10
您可以使用该async with语句来获取异步上下文管理器:
#!/usr/local/bin/python3.5
import asyncio
from aiohttp import ClientSession
sema = asyncio.BoundedSemaphore(5)
async def hello(url):
async with ClientSession() as session:
async with sema, session.get(url) as response:
response = await response.read()
print(response)
loop = asyncio.get_event_loop()
loop.run_until_complete(hello("http://httpbin.org/headers"))
Run Code Online (Sandbox Code Playgroud)
从这里取的例子.该页面也是一个很好的入门asyncio和aiohttp一般.
好的,所以这真的很愚蠢,但我只是在信号量上下文管理器中替换yield from了await它,它运行良好。
sema = asyncio.BoundedSemaphore(5)
async def get_page_text(url):
with (await 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
Run Code Online (Sandbox Code Playgroud)