从协程中提取函数和参数

问题描述:

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

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

async def func(*args): 
    ... 

ret = await remotely(func, x, y) 

引擎盖下,remotely泡菜funcxy,SCP的是不同的服务器,在那里unpickles他们执行func(x,y),泡菜结果,scp就回来了,最后取消它到ret

此API感到反感我,我宁愿有:

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

我能做到这一点,如果我可以腌制由func(x, y)代表的协同程序的对象,但是当我尝试,我得到:

TypeError: can't pickle coroutine objects 

所以我的备用的希望是,我可以从f(x, y)提取fxy,因此这个问题。

所以,当你做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之前定义的任何其他本地变量。

+0

谢谢你。我的同事在我的帖子后不久就设法解决了这个问题,并且破坏了“莳萝”来源,以便我们可以直接腌制协同程序对象。他独立提出了与获取参数值相同的技巧,但想出了一种不同于'__qualname__'的函数。 – dshin

+0

很高兴你解决了它。也许你应该将工作解决方案作为单独的答案发布? – bagrat