python中的async exec

jer*_*rry 5 python exec python-3.x python-asyncio

我想在异步函数中调用exec并执行类似下面的代码(这是无效的):

import asyncio

async def f():
    await exec('x = 1\n' 'await asyncio.sleep(x)')
Run Code Online (Sandbox Code Playgroud)

更确切地说,我希望能够在exec中运行的代码中等待未来.

怎么能实现这一目标?

You*_*ace 7

注意: F字符串仅在python 3.6+中受支持。对于旧版本,使用%s.format()或经典的+级联。

async def aexec(code):
    # Make an async function with the code and `exec` it
    exec(
        f'async def __ex(): ' +
        ''.join(f'\n {l}' for l in code.split('\n'))
    )

    # Get `__ex` from local variables, call it and return the result
    return await locals()['__ex']()
Run Code Online (Sandbox Code Playgroud)

已知的问题:

  • 如果在字符串中使用新行(三引号),则会使格式混乱。

  • 我试着解释一下:如果您有等待的代码,则使用它来代替`eval` /`exec`execute()`函数。执行函数编译输入字符串,并在其中包含所有代码的情况下创建等待函数`__ex`。创建函数后,它将函数调用返回到__ex(),但是由于函数不是直接创建的,因此他使用locals()来获取函数并使用await进行调用。我认为唯一遗漏的一件事是使用globals / locals,您可以选择添加到eval / exec中。 (2认同)

Yuv*_*uss 6

你的问题是你试图等待None对象exec忽略其代码中的返回值,并始终返回None.如果要执行并等待结果,则应使用eval- eval返回给定表达式的值.

你的代码应如下所示:

import asyncio

async def f():
    exec('x = 1')
    await eval('asyncio.sleep(x)')

loop = asyncio.get_event_loop()
loop.run_until_complete(f())
loop.close()
Run Code Online (Sandbox Code Playgroud)