【问题标题】:Call Async Functions Dynamically with exec()使用 exec() 动态调用异步函数
【发布时间】:2017-11-27 08:11:02
【问题描述】:

所以,我正在使用 discord.py 实现一个 Discord Bot,并且我正在尝试根据命令动态调用函数。我能够很好地使用 exec() 测试动态函数调用,但它们似乎与 discord.py 所需的异步调用分崩离析。

所以我想用这个例子做的是调用 hello 函数并通过在聊天中键入 !hello 将 Hello World 打印到不和谐中。

@client.event
async def on_message(message):
    call = 'await ' + message.content.lower()[1:] + '(message)'
    exec(call)

async def hello(message):
    await client.send_message(message.channel, 'Hello World')

不幸的是,这段代码似乎没有做任何事情,我假设是因为 exec() 处理异步调用的方式。任何帮助将不胜感激。

【问题讨论】:

    标签: python python-3.x python-3.5 python-asyncio discord.py


    【解决方案1】:

    而不是exec() 使用globals() 来获取您的功能:

    import asyncio
    
    
    async def main():
        s = "foo"
        param = "hello"
        coro = globals().get(s)
        if coro:
            result = await coro(param)
            print("got:", result)
        else:
            print("unknown function:", s)
    
    
    async def foo(param):
        print(param)
        await asyncio.sleep(0.11)
        return ":-)"
    
    
    loop = asyncio.get_event_loop()
    response = loop.run_until_complete(main())
    loop.close()
    

    但是,允许用户访问 globals() 中的任何内容可能会很危险,但最好将您的命令列入白名单,例如使用:

    import asyncio
    
    my_commands = {}
    
    
    def register(cmd):
        my_commands[cmd.__name__] = cmd
        return cmd
    
    
    async def main():
        s = "foo"
        param = "hello"
        coro = my_commands.get(s)
        if coro:
            result = await coro(param)
            print("got:", result)
        else:
            print("unknown function:", s)
    
    
    @register
    async def foo(param):
        """I am the mighty foo command!"""
        print(param)
        await asyncio.sleep(0.11)
        return ":-)"
    
    
    
    loop = asyncio.get_event_loop()
    response = loop.run_until_complete(main())
    loop.close()
    

    另见:

    for k, v in my_commands.items():
        print("{}: {}".format(k, v.__doc__ or "no docs"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-25
      • 2022-12-04
      • 2013-03-28
      • 2018-12-13
      • 2013-07-12
      • 1970-01-01
      • 2020-04-20
      相关资源
      最近更新 更多