You need to enable JavaScript to run this app. 如何在discordpy机器人中实现可执行异步代码的/run指令?
优惠活动
大模型
产品
解决方案
定价
更多

如何在discordpy机器人中实现可执行异步代码的/run指令?

报错根源

你遇到的SyntaxError: 'await' outside function本质是exec()默认将传入代码作为模块级同步代码块执行,Python语法规定await关键字只能存在于async修饰的协程函数内部,模块级顶层代码无法直接使用await,自然触发语法错误。

实现方案

核心解决思路是将用户传入的带await的代码,包装到自定义的临时异步协程函数内部,再手动驱动协程运行,即可完全规避await的作用域限制,匹配预期交互效果。
可直接复用的代码示例:

from discord.ext import commands
import discord

# 按需求开启对应intents
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!", intents=intents)

@bot.slash_command(name="run", description="执行传入的Python代码")
async def run_code(ctx: commands.Context, code: str):
    # 自动清洗用户传入的代码,兼容markdown代码块格式
    code = code.replace("```py", "").replace("```", "").strip()
    
    # 把用户传入的所有代码包装成异步函数,满足await的语法作用域要求
    wrapped_code = f"""
async def __eval_coro():
    {code}
"""
    # 准备执行作用域,提前暴露常用对象给用户代码
    global_scope = {
        "bot": bot,
        "ctx": ctx,
        "discord": discord,
        "commands": commands
    }
    local_scope = {}
    
    try:
        exec(wrapped_code, global_scope, local_scope)
        # 拿到临时生成的协程函数直接执行
        coro = local_scope["__eval_coro"]
        await coro()
    except Exception as e:
        # 捕获执行异常,将错误信息反馈给调用者
        await ctx.respond(f"代码执行报错:{type(e).__name__}: {str(e)}", ephemeral=True)

执行逻辑验证:当用户输入指令/run code: await ctx.send("hi stackoverflow"),机器人会直接返回hi stackoverflow,和预期效果完全一致。该方案同时兼容多行代码执行,不会限制用户仅输入单行内容。

关键注意事项
  • 极高的安全风险:该指令相当于将bot进程的完整执行权限开放给调用者,无限制开放会让恶意用户随意篡改bot所在服务器、窃取bot权限下的所有数据,甚至在运行bot的主机上执行恶意代码。必须添加严格的权限校验,仅允许bot所有者调用该指令,示例校验逻辑:
    # 加在run指令函数的最开头
    if not await bot.is_owner(ctx.author):
        await ctx.respond("无指令调用权限", ephemeral=True)
        return
    
  • 后续可扩展支持自动捕获代码返回值:比如用户写return "执行成功",自动将返回内容作为消息发送,减少用户重复写ctx.send的冗余代码
  • 如果需要支持更复杂的调试场景,可以在执行作用域内置入常用的第三方库对象,减少用户重复import的操作

内容的提问来源于stack exchange,提问作者BlackHummingbird

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 23:45:05