2017-06-23 23 views
1

私はdiscord.pyを使用してDiscord Botを実装しています。コマンドに基づいて関数を動的に呼び出そうとしています。私はexec()を使って動的関数呼び出しをテストすることができましたが、discord.pyに必要な非同期呼び出しが混乱するようです。exec()で動的に非同期関数を呼び出す

私はこの例では、hello関数を呼び出して、Hello Worldをチャットで!helloと入力することで問題を解決しています。

@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()が非同期呼び出しを処理する方法のために仮定しています。どんな助けもありがとう。

答えて

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()には何もアクセスできるようにすることは、代わりにあなたのコマンドをホワイトリストにはるかに良いだろう、危険なBWE例えば使用したことがあります。

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")) 
関連する問題