从协程中提取函数和参数

时间:2017-04-11 18:04:58

标签: python-asyncio python-3.6

是否可以在python3.6中提取协程对象的函数和参数?

背景:目前我有这样的事情:

async def func(*args):
    ...

ret = await remotely(func, x, y)

在幕后,remotely泡菜funcxy,scp将其发送到不同的服务器,在其中展开它们,执行{ {1}},腌制结果,scp'返回,最后将其解开为func(x,y)

这个API让我感到厌恶,我更喜欢:

ret

如果我可以腌制由ret = await remotely(func(x, y)) 代表的协程对象,我可以这样做,但是当我尝试这样做时,我得到:

func(x, y)

所以我的另一个希望是我可以从TypeError: can't pickle coroutine objects 中提取fxy,因此这个问题。

1 个答案:

答案 0 :(得分:2)

因此,当您执行ret = await remotely(func(x, y))时,实际上为func构建了协程对象。幸运的是,您可以从协同程序对象中提取所需的信息,您可以将其发送以进行远程执行。

首先,您可以使用__qualname__属性获取函数名称。这将为您提供完全限定的名称,即如果协同程序是嵌套的,它将为您提供函数的完整路径。

接下来,您可以从协程的框架对象中提取参数值。

这就是你的remote函数的样子

async def remote(cr):
    # Get the function name
    fname = cr.__qualname__

    # Get the argument values
    frame = cr.cr_frame
    args = frame.f_locals  # dict object

    result = await ...  # your scp stuff

    return result

只有一点需要注意。您应该指出该功能应该仅以您发布的方式使用,即

ret = await remotely(func(x, y))

......换句话说,协程应该是“新鲜的”,而不是中途执行(如果你把它传递给remote,这几乎是不可能的)。否则,f_locals值可能包含在任何await之前定义的任何其他局部变量。