3

嗨,我试图让我的不和谐机器人做我正在输入我的不和谐客户端的事情,我想使用 exec() + 这只是为了测试和实验,所以它是否不安全并不重要。

我的代码的一部分:

import discord

client = discord.Client()

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content.startswith('2B: '):
        exec(message.content[4:])   # <--- here is the exec()
    .
    .
    .

但这是我输入时的错误,

2B: await client.send_message(message.channel, 'please stay quiet -.-')

错误:

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\Users\Shiyon\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\client.py", line 307, in _run_event
    yield from getattr(self, event)(*args, **kwargs)
  File "C:\Users\Shiyon\Desktop\dm_1.py", line 12, in on_message
    exec(message.content[4:])
  File "<string>", line 1
    await client.send_message(message.channel, 'please stay quiet -.-')
               ^
SyntaxError: invalid syntax
4

1 回答 1

5

我相信这可能是你的问题:

请注意,即使在传递给 exec() 函数的代码上下文中,也不能在函数定义之外使用 return 和 yield 语句

来自https://docs.python.org/3/library/functions.html

这应该会更好:

await eval(input)

如果您也希望能够使用非协同程序,您可以在等待评估返回之前进行检查。

这是Rapptz 机器人的一个片段,它似乎做了你想要的事情:

@commands.command(pass_context=True, hidden=True)
@checks.is_owner()
async def debug(self, ctx, *, code : str):
    """Evaluates code."""
    code = code.strip('` ')
    python = '```py\n{}\n```'
    result = None

    env = {
        'bot': self.bot,
        'ctx': ctx,
        'message': ctx.message,
        'server': ctx.message.server,
        'channel': ctx.message.channel,
        'author': ctx.message.author
    }

    env.update(globals())

    try:
        result = eval(code, env)
        if inspect.isawaitable(result):
            result = await result
    except Exception as e:
        await self.bot.say(python.format(type(e).__name__ + ': ' + str(e)))
        return

    await self.bot.say(python.format(result))

解释编辑:

await关键字仅在上下文中有效,因为它在循环中暂停执行方面具有一些魔力。

exec函数总是返回None并丢失它执行的任何语句的返回值。相比之下,该eval函数返回其语句的返回值。

client.send_message(...)返回需要在上下文中等待的可等待对象。通过await在 的返回上使用eval,我们可以轻松地做到这一点,并且通过首先检查它是否可以等待,我们也可以执行非协程。

于 2017-03-26T13:51:13.380 回答