从协程中提取函数和参数
问题描述:
是否可以在python3.6中提取协程对象的函数和参数?从协程中提取函数和参数
背景:目前我有这样的事情:
async def func(*args):
...
ret = await remotely(func, x, y)
引擎盖下,remotely
泡菜func
,x
和y
,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)
提取f
,x
和y
,因此这个问题。
答
所以,当你做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
之前定义的任何其他本地变量。
谢谢你。我的同事在我的帖子后不久就设法解决了这个问题,并且破坏了“莳萝”来源,以便我们可以直接腌制协同程序对象。他独立提出了与获取参数值相同的技巧,但想出了一种不同于'__qualname__'的函数。 – dshin
很高兴你解决了它。也许你应该将工作解决方案作为单独的答案发布? – bagrat