如何正确执行()一个协程

问题描述 投票:0回答:1

我正在写一个Discord机器人,我在测试异步功能时遇到了麻烦。我想通过使用exec()测试它,但我似乎无法正确调用该函数。

我已经尝试了exec() - 使用和不使用await的函数。我看过API docs,但这并没有给我很多洞察我的问题。使用eval(),它返回coroutine对象,但不执行它。

exec()是通过使用异步函数处理消息来完成的

async def f(message)
    #other stuff
    ...
    ...
    exec(strip2(message.content, "exec"))
    return #exec doesn't return anything, so we return to not send an empty message

async函数看起来像这样:

async def move_message(message_id, old_channel, new_channel):
    """
    check the 20 latest messages in old_channel, and if
    one of them matches the id, move it to new_channel
    """
    print("ok")
    async for message in old_channel.history(limit=20):
        #do stuff
        ...
    print("good!")

没有等待,它会给出这个错误:...\commands.py:1: RuntimeWarning: coroutine 'move_message' was never awaited随着等待,它给了我一个SyntaxError

 File "<string>", line 1
    await move_message(message, message.channel, "admin-test-playground")
                     ^
SyntaxError: invalid syntax

我希望功能正确执行,至少打印一些东西。但既不“好”也不“好”!打印我现在拥有的东西。

python python-3.x discord.py
1个回答
1
投票

asyncawait有特殊的语法。 await expr只能在async def上下文中正确解析。所以exec("await function()")将提升SyntaxError,因为exec通过解析语句并运行它来操作,所以它不尊重事件循环。

因此,您不能在异步代码中使用exec来调用异步函数。一旦你了解了异步函数如何在幕后工作,这是有道理的,因为await改变了代码的行为而不是函数调用。

但是,如果您切换到使用eval,您之前使用的代码应该返回您正在调用的协程对象。由于协程对象是等待的,因此您可以使用它,因为您打算使用exec

所以你应该能够做类似的事情

def f(message):
    await eval(message.lstrip('exec '))

并使它正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.