从苗圃对象中捕获 return 值

Capture the return value from nursery objects

使用 trio 和 nursery 对象时,如何捕获从方法中 return 编辑的任何值?

this三重奏网站为例:

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)

我修改了它,每个方法 return 都是一个 list。您将如何捕获 return 值以便我打印它们?

在这种情况下,只需在父级中创建数组并将每个数组传递给需要它的子级即可。

更一般地说,将对象传递给任务;他们可以在上面设置一个属性。您还可以添加一个 Event,以便家长可以等待结果可用。

目前,没有内置的机制。主要是因为我们还没有弄清楚我们希望它如何工作,所以如果您有一些有用的建议:-)。

事实是,对于常规函数,只有一个明显的地方可以访问 return 值 – 调用者正在等待,因此您将 return 值交给他们,完成。对于并发函数,调用者不会等待,所以你还需要一些方法来指定 return 它到哪里,什么时候 return 它,如果有多个函数你必须跟踪哪个一个是 returning 一个值,等等。这不是一个简单的概念。

您想用 return 值做什么?例如,你想在每个函数 returns 时立即打印它们吗?在那种情况下,最简单的事情就是直接从任务中完成:

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"])

你也可以想象那些更奇特的版本——例如,有时当你 运行 并行处理很多任务时,你想要捕获异常,而不仅仅是 return 值,这样一些任务即使其中一些失败了,仍然可以成功。为此,您可以在每个单独的函数周围使用 try/exceptoutcome library. Or when each operation finishes you could put its return value into a trio.Queue,以便另一个任务可以在结果完成时对其进行处理。但希望这能给你一个好的起点:-)