如何在Discord.py中调用函数?调用warn函数遇属性错误求助
问题分析与解决方案
错误根源
你遇到的AttributeError: 'str' object has no attribute 'name'本质是两个问题导致:
- 直接调用作为
hybrid_command的warn函数时,错误传入了未定义的ctx变量(该变量可能在其他上下文被定义为字符串,导致warn函数的member参数被错误的字符串填充)。 warn作为命令函数,依赖commands.Context对象才能正常运行,但on_message事件中并没有这个对象,直接调用命令函数不符合Discord.py的设计逻辑。
另外,代码里guild.get_member(message.author.id)属于冗余操作,message.author本身就是当前消息发送者的discord.Member对象,无需额外查询。
解决方案一:将警告逻辑抽为通用异步函数(推荐)
把警告逻辑从命令函数中分离,做成可复用的异步函数,既可以被命令调用,也能在on_message事件中直接使用:
async def send_warning(message: discord.Message, member: discord.Member): # 优先尝试给用户发私信警告 try: await member.send(f"Please, {member.name} do not send any form of bad words, Thank you!") except discord.Forbidden: # 用户关闭私信时,在消息频道公开警告 await message.channel.send(f"{member.mention}, please do not send any form of bad words, Thank you!") # 保留warn命令,调用通用警告函数 @bot.hybrid_command() async def warn(ctx: commands.Context, member: discord.Member): await send_warning(ctx.message, member) await ctx.send(f"Warning sent to {member.name}!", ephemeral=True) @bot.event async def on_message(message): guild = bot.get_guild(SEVER_ID) if guild is None: print("No Guild") return channel = guild.get_channel(REPORT_CHANNEL) if message.author == bot.user: return result = profanity.contains_profanity(message.content) if result: await channel.send(f"**Message: **{message.content} | **User: **{message.author.name}") await channel.send("<@&1284787770874658939>") # 直接使用message.author作为成员对象 await send_warning(message, message.author) await message.delete() # 必须放在事件末尾,否则会导致命令无法被处理 await bot.process_commands(message)
解决方案二:通过bot.invoke调用命令(不推荐)
如果坚持要直接调用warn命令,需要手动构建命令上下文,使用bot.invoke方法触发命令:
@bot.hybrid_command() async def warn(ctx: commands.Context, member: discord.Member): await ctx.send(f"Please, {member.name} do not send any form of bad words, Thank you!", ephemeral=True) @bot.event async def on_message(message): guild = bot.get_guild(SEVER_ID) if guild is None: print("No Guild") return channel = guild.get_channel(REPORT_CHANNEL) if message.author == bot.user: return result = profanity.contains_profanity(message.content) if result: await channel.send(f"**Message: **{message.content} | **User: **{message.author.name}") await channel.send("<@&1284787770874658939>") # 构建命令上下文并调用warn命令 ctx = await bot.get_context(message) await bot.invoke(ctx, f"warn {message.author.mention}") await message.delete() await bot.process_commands(message)
关键注意事项
await bot.process_commands(message)必须放在on_message事件的最后,否则会导致部分命令无法被Discord.py处理。- 发送警告时加入异常捕获,避免因用户关闭私信权限导致报错。
内容的提问来源于stack exchange,提问作者HOGANCLAN236
相关产品推荐
相关产品推荐

