如何在discord.py中实现支持多参数的ReasonConverter?
解决discord.py中Moderation命令的可变长度Reason参数问题
最简方案:利用discord.py的自动合并剩余参数特性
你之前用*reasons: str再手动join的方式完全可以简化——discord.py支持在参数列表中用*,标记后续参数为"接收所有剩余输入"的单个字符串参数,不需要手动拼接:
import discord from discord.ext import commands class Moderation(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot @commands.command() async def ban(self, ctx, member: discord.Member, *, reason: str = "No reason provided"): # reason已经是合并后的完整字符串,直接使用即可 await member.ban(reason=reason) await ctx.send(f"Banned {member.mention} for: {reason}")
这样用户输入!ban @JohnDoe spamming in general chat时,reason会直接被赋值为"spamming in general chat",无需额外处理。
自定义Converter实现需求拓展
如果需要对reason做自定义处理(比如过滤敏感内容、清理@everyone提及、验证长度等),可以结合自定义Converter和上述*,语法,让Converter直接处理完整的reason字符串:
class ReasonConverter(commands.Converter): async def convert(self, ctx, reason: str): # 自定义处理逻辑示例:移除@everyone/@here提及的可触发效果 cleaned_reason = reason.replace("@everyone", "@\u200beveryone").replace("@here", "@\u200bhere") # 验证长度不超过Discord限制(200字符) if len(cleaned_reason) > 200: raise commands.BadArgument("Reason cannot exceed 200 characters.") return cleaned_reason class Moderation(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot @commands.command() async def ban(self, ctx, member: discord.Member, *, reason: ReasonConverter = "No reason provided"): await member.ban(reason=reason) await ctx.send(f"Banned {member.mention} for: {reason}")
这里的关键是*, reason: ReasonConverter——*,确保所有剩余输入被合并为单个字符串传入Converter的convert方法,而非拆分多个参数,完美解决你之前遇到的空格拆分问题。
为什么之前的Converter方案失效?
你之前尝试的Converter只处理单个参数,是因为没有使用*,标记参数为"剩余内容接收者"。默认情况下,discord.py会按空格拆分输入为多个参数,每个参数单独经过Converter处理;而*,会改变这种行为,将所有剩余输入作为一个整体传递给后续参数的Converter。
内容的提问来源于stack exchange,提问作者Windows Documentation Sucks
相关产品推荐
相关产品推荐

