Discord.py编写机器人调用ctx触发NameError未定义错误如何解决?
问题原因
你遇到的NameError: name 'ctx' is not defined错误由三个核心问题导致:
- ctx是discord.py命令框架自动注入的上下文对象,仅在使用
@bot.command装饰器注册的命令函数中会自动传入,你在on_message事件中没有定义过名为ctx的变量,直接调用purge(ctx)自然会报错 - 你给自定义的
purge函数错误添加了@client.event装饰器,event装饰器仅用于监听Discord的系统事件(比如on_message、on_ready),不能用来装饰自定义业务函数 - 你参考的教程大概率使用的是
discord.ext.commands命令框架,而你当前用的是基础的Client事件监听模式,两种写法的参数传递逻辑不同
修正方案
方案1:保留现有on_message逻辑,调整参数传递
直接把你拿到的message对象传给purge函数即可,无需使用ctx:
import os import discord # 注意:discord.py 2.0+ 版本需要开启消息内容意图 # 你需要先在Discord开发者后台的Bot设置页打开Message Content Intent开关 client = discord.Client(intents=discord.Intents.all()) # 去掉错误的@client.event装饰器,参数改为message async def purge(message): """clear 3 messages from current channel""" channel = message.channel await message.delete() await channel.purge(limit=3) return True @client.event async def on_message(message): if message.content.startswith("purge"): # 传入当前触发命令的message对象,不要传不存在的ctx await purge(message) client.run(os.environ['TOKEN'])
修正后你发送purge即可触发删除功能。
方案2:使用官方命令框架,符合教程写法
这种方式更符合主流教程的用法,框架会自动处理命令匹配、ctx注入,不需要你手写on_message判断前缀:
import os import discord from discord.ext import commands # 初始化命令机器人,这里设置命令前缀为!,可自行修改 bot = commands.Bot(command_prefix="!", intents=discord.Intents.all()) # 用@bot.command注册命令,框架会自动传入ctx参数 @bot.command(name="purge") async def purge(ctx): """clear 3 messages from current channel""" await ctx.message.delete() await ctx.channel.purge(limit=3) @bot.event async def on_ready(): print(f"机器人登录成功: {bot.user}") bot.run(os.environ['TOKEN'])
修正后你发送!purge即可触发删除功能。
额外注意事项
- repl.it托管时需要确保你已经把机器人TOKEN正确配置在环境变量的
TOKEN字段中,不要硬编码到代码里 - 必须在Discord开发者后台开启对应权限,否则机器人无法读取消息内容、也无法删除消息
内容的提问来源于stack exchange,提问作者Bonzo 998
相关产品推荐
相关产品推荐

