Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 从任务创建函数返回异步IO回调结果_Python 3.x_Asynchronous_Callback_Python Asyncio - Fatal编程技术网

Python 3.x 从任务创建函数返回异步IO回调结果

Python 3.x 从任务创建函数返回异步IO回调结果,python-3.x,asynchronous,callback,python-asyncio,Python 3.x,Asynchronous,Callback,Python Asyncio,我试图包装一个异步函数,这样我就可以使用它,而无需在某些文件中导入asyncio。最终目标是使用异步函数,但能够正常调用它们并返回结果 如何从回调函数printing(task)访问结果,并将其用作我的make_task(x)函数的返回 MWE: #/usr/bin/env蟒蛇3.7 导入异步 loop=asyncio.get\u event\u loop() def make_任务(x):#可以在没有异步的情况下使用 任务=循环。创建任务(我的异步(x)) 任务.添加\u完成\u回调(打印)

我试图包装一个异步函数,这样我就可以使用它,而无需在某些文件中导入asyncio。最终目标是使用异步函数,但能够正常调用它们并返回结果

如何从回调函数
printing(task)
访问结果,并将其用作我的
make_task(x)
函数的返回

MWE:

#/usr/bin/env蟒蛇3.7
导入异步
loop=asyncio.get\u event\u loop()
def make_任务(x):#可以在没有异步的情况下使用
任务=循环。创建任务(我的异步(x))
任务.添加\u完成\u回调(打印)
#返回以获取
def打印(任务):
打印('睡眠完成:%s'%task.done())
打印('结果:%s'%task.result())
return task.result()#如何访问此返回?
async def my_async(x):#处理实际的异步运行
打印('启动我的异步')
res=等待我的睡眠(x)
return res#我希望在实际回调中最终使用的值
异步定义我的睡眠(x):
打印('正在为%d“%x”启动睡眠)
等待asyncio.sleep(x)
返回x**2
异步定义my_coro(*coro):
return wait asyncio.gather(*coro)
val1=生成任务(4)
val2=生成任务(5)
循环。运行直到完成(my_coro(asyncio.sleep(6)))
打印(val1)
打印(val2)

不使用回调,您可以使
打印
成为一个协同程序,并
等待
原始协同程序,例如
my\u async
make_task
然后可以从
打印(my_async(…)
中创建一个任务,这将使
打印的返回值作为任务结果可用。换句话说,要从打印中返回一个值,只需-return即可

例如,如果您这样定义
make_task
printing
,并保持程序的其余部分不变:

def make_task(x):
    task = loop.create_task(printing(my_async(x)))
    return task

async def printing(coro):
    coro_result = await coro
    print('sleep done')
    print('results: %s' % coro_result)
    return coro_result
结果是:

Starting my async
starting sleep for 4
Starting my async
starting sleep for 5
sleep done
results: 16
sleep done
results: 25
<Task finished coro=<printing() done, defined at result1.py:11> result=16>
<Task finished coro=<printing() done, defined at result1.py:11> result=25>
启动我的异步
开始睡眠4小时
启动我的异步
开始5天的睡眠
睡个好觉
结果:16
睡个好觉
结果:25

如果我理解正确,您希望使用异步函数,但不希望在顶级代码中写入
异步
/
等待

如果是这样,恐怕用
asyncio
无法实现
asyncio
希望您在异步内容发生的任何地方编写
async
/
等待
,这是有意的:强制显式标记可能的上下文切换位置是
asyncio
解决并发相关问题的方法(否则很难解决)。阅读更多信息


如果您仍然希望使用异步功能并“像往常一样使用代码”,请查看其他解决方案,如。

是的,但问题是
make\u任务的返回。我唯一能返回的是task对象,我想返回值
x**2
@Kajsa,这在问题中并不明显,因为您的代码在顶级调用
make_task
两次,这让您看起来好像真的想在那个时候完成任务(而不是等待任务完成),然后检索这些值。那么,是哪一个呢?您希望
make_task
阻止当前线程直到任务完成,还是希望它将任务提交到事件循环?我在问题中明确指出,我希望“访问回调函数printing(task)的结果,并将其用作make_task(x)函数的返回”。因此,如果调用
make_task
的模块看起来像一个正常的方法,那么我想要的是将任务添加到循环中,而不是阻止异步代码的其余部分,而是从外部执行。我明白,这是一件非常规的事情,可能根本不可能做到。我想我还是会问,因为可能有一种解决方法,使调用看起来像是返回了预期的值。@Kajsa那么,您想
make_task
阻止当前线程,直到结果可用吗?