discord.py报错:'Member'对象无'author'属性,求封禁命令修复
问题修复方案
错误原因
你遇到的AttributeError是因为参数传递顺序错误:
ban_member函数的第一个参数是ctx(命令上下文),但你在ban_command里调用时,直接把member作为第一个参数传了进去,导致ban_member里的ctx变量实际是Member对象,自然没有author属性。- 另外,
ban_member被错误标记为@commands.Cog.listener(),这个装饰器是用来注册事件监听器(比如消息、成员加入事件)的,你的函数是工具函数,不需要这个装饰器。
修复后的完整代码
1. 修正ban_member函数
# 去掉@commands.Cog.listener()装饰器,这不是事件监听函数 async def ban_member(self, ctx, member: discord.Member = None, *, reason=None): author = ctx.author self.staff_log_channel = self.bot.get_channel(designated_channel) embed = Embed(description=f'**Moderation Protocol - Ban:**', color=0x3B0311, timestamp=datetime.utcnow()) embed.set_author(name=f'{self.bot.user.name}', icon_url=self.bot.user.avatar_url) embed.set_footer(text=f'Moderator: {author.name} ({author.id}) │\nMember ID: {member.id}') embed.add_field(name=f'You have been banned in {ctx.guild}.', value=f'This decision was made by the staff team and is the appropriate action for this case.', inline=False) if reason is not None: # 把执行者信息加入reason,方便审计日志查看 full_reason = f"{author.name} ({author.id}): {reason}" embed.add_field(name=f'**Provided Reason**:', value=f'{reason}', inline=False) else: full_reason = f"{author.name} ({author.id}): No reason provided" try: await member.send(embed=embed) except discord.Forbidden: # 捕获用户关闭DM的情况,避免无意义报错 pass await self.clearwarn(ctx, member) # 使用带执行者信息的full_reason,审计日志会显示这个内容 await member.ban(reason=full_reason) await ctx.channel.send(f'{member.name} has been banned from the server.')
2. 修正ban_command的调用
@commands.command(aliases=['bn']) @commands.has_permissions(ban_members=True) async def ban_command(self, ctx: commands.Context, member: discord.Member = None, *, reason=None): # 保留你原来的embeds和消息逻辑 # ... # 调用ban_member时,第一个参数传ctx,顺序要对应 await self.ban_member(ctx, member, reason=reason)
关键修复点解释
参数顺序修正:
调用ban_member时必须把ctx作为第一个参数传递,这样ban_member里的ctx才是正确的命令上下文对象,能正常获取ctx.author(即命令调用者)。移除错误的装饰器:
@commands.Cog.listener()是用于注册Discord事件的,比如on_message,你的ban_member是被命令调用的工具函数,不需要这个装饰器,否则可能会被错误注册为事件监听器,引发未知问题。审计日志优化:
原来的审计日志显示机器人为执行者是正常的(因为是机器人执行的ban操作),但我们可以把调用者的信息加入ban的reason中,这样在服务器审计日志里,就能看到是谁发起的封禁操作,解决你无法追踪调用者的问题。
内容的提问来源于stack exchange,提问作者Daddy Myers
相关产品推荐
相关产品推荐

