无法在 exec 中等待
Cannot await in exec
嗨,我正在尝试让我的 discord 机器人执行我在 discord 客户端中输入的内容,我想使用 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
我相信这可能是您的问题:
Be aware that the return and yield statements may not be used outside of function definitions even within the context of code passed to the exec() function
来自 https://docs.python.org/3/library/functions.html
这应该会更好:
await eval(input)
如果您也希望能够使用非协程,您可以在等待 return 评估之前进行检查。
这是 Rapptz's bot 中的一个片段,它似乎可以满足您的需求:
@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
函数总是 returns None
并丢失它执行的任何语句的 return 值。相比之下,eval
函数 return 是其语句的 return 值。
client.send_message(...)
returns 一个需要在上下文中等待的可等待对象。通过在 eval
的 return 上使用 await
,我们可以很容易地做到这一点,通过首先检查它是否可等待,我们也可以执行非协程。
嗨,我正在尝试让我的 discord 机器人执行我在 discord 客户端中输入的内容,我想使用 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
我相信这可能是您的问题:
Be aware that the return and yield statements may not be used outside of function definitions even within the context of code passed to the exec() function
来自 https://docs.python.org/3/library/functions.html
这应该会更好:
await eval(input)
如果您也希望能够使用非协程,您可以在等待 return 评估之前进行检查。
这是 Rapptz's bot 中的一个片段,它似乎可以满足您的需求:
@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
函数总是 returns None
并丢失它执行的任何语句的 return 值。相比之下,eval
函数 return 是其语句的 return 值。
client.send_message(...)
returns 一个需要在上下文中等待的可等待对象。通过在 eval
的 return 上使用 await
,我们可以很容易地做到这一点,通过首先检查它是否可等待,我们也可以执行非协程。