JawsIk
@JawsIk
Python Django, Lua, ЧПУ-станки(ArtCam, Aspire)

Как сделать асинхронным бесконечный перебор списка?

Имеется код. Очень простой. Есть список со значениями.
В функции main стоит конструкция с бесконечным циклом, суть которого поочерёдный перебор значений из списка. (В идеале список должен быть пополняемым разными значениями), но для примера используемое значение удаляется из начала списка и добавляется снова в конец. Тем самым образуется некая очередь.
В процессе перебора отправляется запрос на сайт через функцию get_html
Для удобства в main есть подсчёт итераций через переменную counter_

И всё это прекрасно работает, но как сделать эту конструкцию асинхронной, ума не приложу. Нигде нет примера именно такого простого подхода с перебором. Я пересмотрел кучу примеров, но так толком и не могу понять, как мне реализовать вот именно такой подход. Когда есть список или какая-то очередь c пополняемыми значениями.

Подскажите, как мой код сделать асинхронным при помощи asyncio и aiohttp?

from datetime import datetime
import requests
import asyncio
import aiohttp

LIST_ = ['Shishel','Mishel','Perdnul','Vishel',
         'Papa','Mama',"Mila",'Ramu',
         'Eniki','Beniki','Eli','Vareniki',
         'Kreks','Feks','Peks','Keks']

def get_html(data):
    url = f'http://httpbin.org/get?acc={data}'
    try:
        r = requests.get(url)
        return r.json()['args']['acc']
    except:
        return 'failed'



def main():
    accs = LIST_
    counter_ = 0
    start = datetime.now()

    while accs:
        counter_ += 1
        one = accs.pop(0)
        print (  counter_ , get_html(one) )
        accs.append( one )
        if counter_ == len(accs):
            counter_ = 0
            end = datetime.now()
            print('*' * 10, end - start, '*' * 10)
            start = end



if __name__ == '__main__':
    main()
  • Вопрос задан
  • 755 просмотров
Решения вопроса 1
@cython
Можно вынести итерацию цикла в отдельную асинхронную функцию, которая будет работать, как фоновая задача
from datetime import datetime
import requests
import asyncio
import aiohttp

LIST_ = ['Shishel','Mishel','Perdnul','Vishel',
         'Papa','Mama',"Mila",'Ramu',
         'Eniki','Beniki','Eli','Vareniki',
         'Kreks','Feks','Peks','Keks']

accs = LIST_
counter_ = 0
start = datetime.now()


async def get_html(data):
    url = f'http://httpbin.org/get?acc={data}'
    try:
    	async with aiohttp.ClientSession() as session:
        	async with session.get(url) as r:
        		return (await r.json())['args']['acc']
    except:
        return 'failed'


async def acc():
    global counter_, accs, start
    counter_ += 1
    one = accs.pop(0)
    print(counter_, await get_html(one), len(accs))
    accs.append( one )
    if counter_ == len(accs):
        counter_ = 0
        end = datetime.now()
        print('*' * 10, end - start, '*' * 10)
        start = end


async def main():
    tasks = []
    while accs:
        for _ in range(10):  # Ограничение на 10 задач, которые выполняются одновременно
            tasks.append(asyncio.get_event_loop().create_task(acc()))
        await asyncio.wait(tasks)  # Ожидание выполнения всех задач


if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы