从协程中提取函数和参数

Extracting the function and arguments from a coroutine

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

上下文:目前我有这样的东西:

async def func(*args):
    ...

ret = await remotely(func, x, y)

在引擎盖下,remotely 腌制 funcxy,scp 到不同的服务器,在那里它 unp​​ickles,执行 func(x,y),腌制结果,scp 返回,最后将其解腌制为 ret

这个API让我觉得很反感,我更喜欢:

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

如果我可以 pickle 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))

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