Как сжать код, который выбирает, сколько параллельных задач выполняется на основе ввода?

У меня есть проект Scrapper, который работает с асинхронными запросами, просит библиотеки и трио. Я хотел бы выбрать, сколько параллельных задач выполняется на основе ввода, но мой код длинный и примитивный.

Я использую объект трио для порождения и питомника для одновременных задач (документы: https://trio.readthedocs.io/en/latest/reference-core.html)

Вот мой неаккуратный код:

import trio
import asks
Number_of_workers = input("how many workers do you want?: ") #How many tasks I want between 1 and 5

async def child1(s):
    r = await s.get("https://example.com", params={"example":"example"})
    print("do something with", r.text)

async def child2():
    r = await s.get("https://example.com", params={"example":"example"})
    print("do something with", r.text)

async def child3():
    r = await s.get("https://example.com", params={"example":"example"})
    print("do something with", r.text)

async def child4():
    r = await s.get("https://example.com", params={"example":"example"})
    print("do something with", r.text)

async def child5():
    r = await s.get("https://example.com", params={"example":"example"})
    print("do something with", r.text)

async def parent(): 
    s = Session(connections=5)
    async with trio.open_nursery() as nursery:
        if int(Number_of_workers) == 1:
            nursery.start_soon(child1, s)

        elif int(Number_of_workers) == 2:
            nursery.start_soon(child1, s)
            nursery.start_soon(child2, s)

        elif int(Number_of_workers) == 3:
            nursery.start_soon(child1, s)
            nursery.start_soon(child2, s)
            nursery.start_soon(child3, s)

        elif int(Number_of_workers) == 4:
            nursery.start_soon(child1, s)
            nursery.start_soon(child2, s)
            nursery.start_soon(child3, s)
            nursery.start_soon(child4, s)

        elif int(Number_of_workers) == 5:
            nursery.start_soon(child1, s)
            nursery.start_soon(child2, s)
            nursery.start_soon(child3, s)
            nursery.start_soon(child4, s)
            nursery.start_soon(child5, s)
trio.run(parent)

Я думаю, вы можете понять, к чему я клоню, этот пример кода теоретически работает, но он очень длинный для чего-то, что может быть сокращено до меньшего количества строк кода.

Такая схема становится особенно длительной при работе с 10 или 20 работниками и всегда ограничивается заранее определенной суммой.

Внутри себя каждый дочерний элемент - это один и тот же код, он просто получает разные данные (например, params и url) из файла.py внешнего модуля с помощью importlib.

Есть ли способ сократить это до более оптимизированного кода?

1 ответ

Решение

Вы можете использовать цикл!

async def child(s):
    r = await s.get("https://example.com", params={"example":"example"})
    print("do something with", r.text)

async def parent(): 
    s = Session(connections=5)
    async with trio.open_nursery() as nursery:
        for i in range(Number_of_workers):
            nursery.start_soon(child, s)

Редактировать: вот отдельная демонстрация, которую вы можете запустить, чтобы убедить себя, что это на самом деле запускает параллельные задачи. Он также демонстрирует, как вы можете передавать разные значения параметров разным задачам, чтобы они выполняли разные задачи - в этом случае выведите разные сообщения:

import trio

Number_of_workers = 10

async def child(i):
    print("child {}: started".format(i))
    await trio.sleep(5)
    print("child {}: finished".format(i))

async def parent():
    async with trio.open_nursery() as nursery:
        for i in range(Number_of_workers):
            nursery.start_soon(child, i)

trio.run(parent)

Попробуйте и посмотрите!

Другие вопросы по тегам