Discord.py音乐机器人报错:缺少必填位置参数'ctx'
Discord音乐机器人Skip命令执行报错问题
问题概述
开发Discord音乐机器人时,所有命令均触发相同异常,以Skip命令为例,执行时提示缺少ctx参数。怀疑是否因使用discord.py已弃用语法导致,寻求解决方案。
相关代码片段
音乐Cog实现(dustobot.py)
class music(commands.Cog): def __init__(self, bot): self.bot = bot self.is_playing = False self.is_paused = False self.music_queue = [] self.YDL_OPTIONS = {"format": "bestaudio", "noplaylist": "True"} self.FFMPEG_OPTIONS = {"before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", "options": "-vn"} self.vc = None async def play_music(self, ctx): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]["source"] if self.vc == None or not self.vc.is_connected(): self.vc == await self.music_queue[0][1].connect() if self.vc == None: await ctx.send("抱歉,我无法加入语音频道") return else: await self.vc.move_to(self.music_queue[0][1]) self.music_queue.pop(0) self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next()) else: self.is_playing = False def play_next(self): if len(self.music_queue) > 0: self.is_playing = True m_url = self.music_queue[0][0]["source"] self.music_queue.pop(0) self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next()) else: self.is_playing = False def search(self, item): with YoutubeDL(self.YDL_OPTIONS) as ydl: try: info = ydl.extract_info("ytsearch:{0}".format(item), download=False)["entries"][0] except Exception: return False return {"source": info["formats"][0]["url"], "title": info["title"]} async def setup(client): await client.add_cog(music(client))
Bot类与Skip命令(bot.py)
class MyBot(commands.Bot): async def setup_hook(self): await self.load_extension("dustobot") @commands.command(aliases=["s"], help="跳过当前播放的歌曲") async def skip(self, ctx, *args): if self.vc != None and self.vc: self.vc.stop() await self.play_music(ctx) # 播放队列中的下一首歌曲
主入口文件(main.py)
import os import discord from dustobot import music # 导入音乐类 from dotenv import load_dotenv from discord.ext import commands load_dotenv() TOKEN = os.getenv('DISCORD_TOKEN') intents = discord.Intents.default() intents.message_content = True client = commands.Bot(command_prefix="!", intents=intents) client.remove_command("help") # 自定义了help命令 if __name__ == "__main__": client.run(TOKEN)
错误信息
2023-01-21 12:28:37 ERROR discord.ext.commands.bot Ignoring exception in command skip Traceback (most recent call last): File "C:\Users\private_path\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\ext\commands\core.py", line 229, in wrapped ret = await coro(*args, **kwargs) TypeError: music.skip() missing 1 required positional argument: 'ctx' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\private_path\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\ext\commands\bot.py", line 1349, in invoke await ctx.command.invoke(ctx) File "C:\Users\private_path\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\ext\commands\core.py", line 1023, in invoke await injected(*ctx.args, **ctx.kwargs) # type: ignore File "C:\Users\private_path\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\ext\commands\core.py", line 238, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: music.skip() missing 1 required positional argument: 'ctx'
疑问
是否因使用discord.py已弃用语法导致该错误?
解决方案
核心问题是命令定义位置错误+语法疏漏,和弃用语法无关:
- 命令未绑定到Cog实例:你把
skip命令定义在了MyBot类外部,而非musicCog内部,导致命令无法获取Cog实例的上下文,触发缺少ctx的报错。 - 赋值运算符错误:
play_music方法中self.vc == await ...是比较操作,应改为self.vc = await ...,否则self.vc始终为None,无法正常连接语音频道。
修正步骤:
1. 将Skip命令移入music Cog内部
class music(commands.Cog): def __init__(self, bot): self.bot = bot # 其余初始化代码不变 # 其余方法(play_music、play_next、search)不变 @commands.command(aliases=["s"], help="跳过当前播放的歌曲") async def skip(self, ctx, *args): if self.vc is not None and self.vc.is_playing(): self.vc.stop() await self.play_music(ctx)
2. 修正play_music中的赋值错误
将:
self.vc == await self.music_queue[0][1].connect()
改为:
self.vc = await self.music_queue[0][1].connect()
3. 调整main.py使用自定义MyBot类
否则setup_hook不会执行,无法加载Cog:
# main.py import os import discord from bot import MyBot from dotenv import load_dotenv load_dotenv() TOKEN = os.getenv('DISCORD_TOKEN') intents = discord.Intents.default() intents.message_content = True client = MyBot(command_prefix="!", intents=intents) client.remove_command("help") if __name__ == "__main__": client.run(TOKEN)
调整后命令可正确绑定到Cog实例,获取ctx参数,同时解决语音连接的赋值问题。
内容的提问来源于stack exchange,提问作者Coder_0511
相关产品推荐
相关产品推荐

