[英]Python asyncio.semaphore in async-await function
我正在尝试自学 Python 的异步功能。 为此,我构建了一个异步 web 刮板。 我想限制我一次打开的连接总数,以便成为服务器上的好公民。 I know that semaphore's are a good solution, and the asyncio library has a semaphore class built in. My issue is that Python complains when using yield from
in an async
function as you are combining yield
and await
syntax. 以下是我正在使用的确切语法...
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
装饰器我对 Python 的异步功能非常陌生,所以我可能会遗漏一些明显的东西。
您可以使用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"))
从这里取的例子。 该页面也是asyncio
和aiohttp
一个很好的入门asyncio
。
OK,所以这是真的很傻,但我只是取代了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
仅用于信号量:
sem = asyncio.Semaphore(10)
# ... later
async with sem:
# work with shared resource
这相当于:
sem = asyncio.Semaphore(10)
# ... later
await sem.acquire()
try:
# work with shared resource
finally:
sem.release()
参考: https://docs.python.org/3/library/asyncio-sync.html#asyncio.Semaphore
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.