Захватить возвращаемое значение из объектов питомника

При использовании трио и nursery объекты, как вы захватываете любое значение, которое было возвращено из метода?

Возьмите этот пример с сайта трио:

async def append_fruits():
    fruits = []
    fruits.append("Apple")
    fruits.append("Orange")
    return fruits

async def numbers():
    numbers = []
    numbers.append(1)
    numbers.append(2)
    return numbers

async def parent():
    async with trio.open_nursery() as nursery:
        nursery.start_soon(append_fruits)
        nursery.start_soon(numbers)

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

2 ответа

Решение

В настоящее время нет встроенного механизма для этого. Главным образом потому, что мы не выяснили, как бы мы хотели, чтобы это работало, поэтому, если у вас есть предложения, которые будут полезны:-).

Дело в том, что с обычными функциями есть одно очевидное место для доступа к возвращаемому значению - вызывающий ожидает, поэтому вы вручаете им возвращаемое значение, готово. При одновременных функциях вызывающая сторона не ждет, поэтому вам также нужно каким-то образом указать, куда ее возвращать, когда возвращать, если есть несколько функций, вы должны отслеживать, какая из них возвращает значение, и т.д. на. Это не такая простая концепция.

Что вы хотите сделать с возвращаемыми значениями? Вы хотите, скажем, напечатать их сразу, когда каждая функция вернется? В таком случае проще всего сделать это прямо из задач:

async def print_fruits():
    print(await fruits())

async def print_numbers():
    print(await numbers())

async with trio.open_nursery() as nursery:
    nursery.start_soon(print_fruits)
    nursery.start_soon(print_numbers)

Вы можете даже включить это во вспомогательную функцию:

async def call_then_print(fn):
    print(await fn())

async with trio.open_nursery() as nursery:
    nursery.start_soon(call_then_print, fruits)
    nursery.start_soon(call_then_print, numbers)

Или, может быть, вы хотите поместить их в структуру данных, чтобы посмотреть позже?

results = {}

async def store_fruits_in_results_dict():
    results["fruits"] = await fruits()

async def store_numbers_in_results_dict():
    results["numbers"] = await numbers()

async with trio.open_nursery() as nursery:
    nursery.start_soon(store_fruits_in_results_dict)
    nursery.start_soon(store_numbers_in_results_dict)

# This is after the nursery block, so we know that the dict is fully filled in:
print(results["fruits"])
print(results["numbers"])

Вы также можете представить их более причудливые версии - например, иногда, когда вы выполняете много задач параллельно, вы хотите захватывать исключения, а не просто возвращать значения, так что некоторые задачи все еще могут быть успешными, даже если некоторые из них завершатся неудачно. Для этого вы можете использовать try / except вокруг каждой отдельной функции, или outcome библиотека. Или когда каждая операция заканчивается, вы можете поместить ее возвращаемое значение в trio.Queue, так что другая задача может обработать результаты по мере их завершения. Но, надеюсь, это даст вам хорошую отправную точку:-)

В этом случае просто создайте массивы в родительском элементе и передайте каждый из них нуждающемуся дочернему элементу.

В более общем случае, передайте объект задачам; они могут установить атрибут на него. Вы также можете добавить Event так что родитель может ждать результатов, которые будут доступны.

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