Python 从作为异步任务运行的函数中获取值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32456881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting values from functions that run as asyncio tasks
提问by Saad Aleem
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. How do I go about accomplishing this?
因为这会使 this 成为关键字参数。我该如何去完成这个?
采纳答案by jfs
The coroutines work as is. Just use the returned value from loop.run_until_complete()
and call asyncio.gather()
to collect multiple results:
协程按原样工作。只需使用 fromloop.run_until_complete()
和callasyncio.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
回答by dano
loop.run_until_complete
returns the value returned by the function you pass into it. So, it will return the output of asyncio.wait
:
loop.run_until_complete
返回您传递给它的函数返回的值。因此,它将返回以下输出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())
回答by Petr Javorik
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. As soon as future is updated it passes its future.result() to the callback function which is bound with given future. See code below:
如果您想在协程结束后立即使用协程返回的任何值,您可以将未来对象传递给 coro 并通过计算值更新这个未来。一旦future 被更新,它就会将它的future.result() 传递给与给定future 绑定的回调函数。见下面的代码:
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)