简体   繁体   English

从作为异步任务运行的函数中获取值

[英]Getting values from functions that run as asyncio tasks

I was trying the following code:我正在尝试以下代码:

import asyncio

@asyncio.coroutine
def func_normal():
        print("A")
        yield from asyncio.sleep(5)
        print("B")
        return 'saad'

@asyncio.coroutine
def func_infinite():
    i = 0
    while i<10:
        print("--"+str(i))
        i = i+1
    return('saad2')

loop = asyncio.get_event_loop()

tasks = [
    asyncio.async(func_normal()),
    asyncio.async(func_infinite())]

loop.run_until_complete(asyncio.wait(tasks))
loop.close()

I can't figure out how to get values in variables from these functions.我不知道如何从这些函数中获取变量中的值。 I can't do this:我不能这样做:

asyncio.async(a = func_infinite())

as this would make this a keyword argument.因为这会使 this 成为关键字参数。 How do I go about accomplishing this?我该如何完成这个任务?

The coroutines work as is. 协同程序按原样工作。 Just use the returned value from loop.run_until_complete() and call asyncio.gather() to collect multiple results : 只需使用loop.run_until_complete()返回的值并调用asyncio.gather()来收集多个结果

#!/usr/bin/env python3
import asyncio

@asyncio.coroutine
def func_normal():
    print('A')
    yield from asyncio.sleep(5)
    print('B')
    return 'saad'

@asyncio.coroutine
def func_infinite():
    for i in range(10):
        print("--%d" % i)
    return 'saad2'

loop = asyncio.get_event_loop()
tasks = func_normal(), func_infinite()
a, b = loop.run_until_complete(asyncio.gather(*tasks))
print("func_normal()={a}, func_infinite()={b}".format(**vars()))
loop.close()

Output 产量

--0
--1
--2
--3
--4
--5
--6
--7
--8
--9
A
B
func_normal()=saad, func_infinite()=saad2

loop.run_until_complete returns the value returned by the function you pass into it. loop.run_until_complete返回您传递给它的函数返回的值。 So, it will return the output of asyncio.wait : 因此,它将返回asyncio.wait的输出:

import asyncio

@asyncio.coroutine
def func_normal():
    print("A")
    yield from asyncio.sleep(5)
    print("B")
    return 'saad'

@asyncio.coroutine
def func_infinite():
    i = 0
    while i<10:
        print("--"+str(i))
        i = i+1
    return('saad2')

loop = asyncio.get_event_loop()

tasks = [
    asyncio.async(func_normal()),
    asyncio.async(func_infinite())]

done, _ = loop.run_until_complete(asyncio.wait(tasks))
for fut in done:
    print("return value is {}".format(fut.result()))
loop.close()

Output: 输出:

A
--0
--1
--2
--3
--4
--5
--6
--7
--8
--9
B
return value is saad2
return value is saad

You can also access the results directly from the tasks array: 您还可以直接从tasks数组访问结果:

print(tasks[0].result())
print(tasks[1].result())

If you want to use any value returned by coroutine as soon as coroutine ends you can pass future object into the coro and update this future by computed value. 如果你想在协同程序结束时使用协同程序返回的任何值,你可以将未来的对象传递给coro并通过计算值更新此未来。 As soon as future is updated it passes its future.result() to the callback function which is bound with given future. 一旦未来更新,它会将future.result()传递给与给定的未来绑定的回调函数。 See code below: 见下面的代码:

import asyncio


async def func_normal(future):
    print("A")
    await asyncio.sleep(5)
    print("B")
    # return 'saad'
    future.set_result('saad')


async def func_infinite(future):
    i = 0
    while i<10:
        print("--"+str(i))
        i = i+1
    # return('saad2')
    future.set_result('saad2')

def got_result(future):
    print(future.result())

loop = asyncio.get_event_loop()
future1 = asyncio.Future()
future2 = asyncio.Future()

future1.add_done_callback(got_result)
future2.add_done_callback(got_result)

# Coros are automatically wrapped in Tasks by asyncio.wait() 
coros = [
    func_normal(future1),
    func_infinite(future2)]

loop.run_until_complete(asyncio.wait(coros))
loop.close()

The callback function is called with a single argument - the future object which it is bound with. 使用单个参数调用回调函数 - 它与之绑定的未来对象。 If you need to pass more arguments into the callback use partial from functools package: 如果需要将更多参数传递给回调,请使用functools包中的partial:

future1.add_done_callback(functools.partial(print, "future:", argin))

will call 将会通知

print("future:", argin)

I found a solution that I like better:我找到了一个我更喜欢的解决方案:

    loop = asyncio.new_event_loop()
    task = loop.create_task(awaitable(*args, **kwargs))

    loop.run_until_complete(task)

    return task.result()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM