是否可以在python3.6中提取协程对象的函数和参数?
背景:目前我有这样的事情:
async def func(*args):
...
ret = await remotely(func, x, y)
在幕后,remotely
泡菜func
,x
和y
,scp将其发送到不同的服务器,在其中展开它们,执行{ {1}},腌制结果,scp'返回,最后将其解开为func(x,y)
。
这个API让我感到厌恶,我更喜欢:
ret
如果我可以腌制由ret = await remotely(func(x, y))
代表的协程对象,我可以这样做,但是当我尝试这样做时,我得到:
func(x, y)
所以我的另一个希望是我可以从TypeError: can't pickle coroutine objects
中提取f
,x
和y
,因此这个问题。
答案 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
之前定义的任何其他局部变量。