У меня есть часть кода, связанного с вводом-выводом, который в основном занимается веб-скрапингом для моего исследовательского проекта.
Код начинался с императива, затем превратился в списки, которые теперь в основном превратились в генераторы:
if __name__ == '__main__':
while True:
with suppress(Exception):
page = requests.get(baseUrl).content
urls = (baseUrl + link['href'] for link in BeautifulSoup(page,'html.parser').select('.tournament a'))
resources = (scrape_host(url) for url in urls)
keywords = ((keywords_for_resource(referer, site_id), rid) for
referer, site_id, rid in resources)
output = (scrape(years, animals) for years, animals in keywords)
responses = (post_data_with_exception_handling(list(data)) for data in output)
for response in responses:
print(response.status_code)
Такой код действительно хорошо укладывается в моей голове, и, поскольку он основан на генераторах без сохранения большого количества состояния, я решил, что могу довольно легко превратить его в код на основе asyncio
:
async def fetch(session, url):
with async_timeout.timeout(10):
async with session.get(url) as response:
return await response.text()
async def main(loop):
async with aiohttp.ClientSession(loop=loop) as session:
page = await fetch(session,baseUrl)
urls = (baseUrl + link['href'] for link in BeautifulSoup(page,'html.parser').select('.tournament a'))
subpages = (await fetch(session,url) for url in urls)
Однако в Python 3.5 это просто возвращает Syntax error
, поскольку выражение await
не разрешено внутри понимания.
Python 3.6 обещает реализовать асинхронные генераторы в pep 530.
Позволит ли эта функция легко преобразовать код на основе генератора в код asyncio
, или его также потребуется полностью переписать?