[英]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.