discord.py报错:'User'对象无'roles'属性,角色修改失败
嘿,这个问题我之前做Discord机器人的时候也踩过坑!核心原因其实是Discord.py里User对象和Member对象的本质区别,咱们一步步来解决:
为什么会出现这个错误?
在Discord的生态里,User是全局层面的用户账号对象——它只记录用户的基础信息(比如头像、用户名),和具体的服务器没有绑定,所以自然没有roles这种和服务器强相关的属性。而你要修改角色,必须拿到用户在当前服务器里的Member实例,这个对象才包含服务器专属的角色、昵称等信息。
具体解决办法
根据你写命令的方式,分两种场景处理:
场景1:用Discord.py的官方命令框架
如果你的!suspend命令是用@commands.command()装饰器写的,直接在参数里指定类型为discord.Member就行,框架会自动帮你把用户提及转换成对应服务器的Member对象:
import asyncio from discord.utils import get @bot.command() async def suspend(ctx, member: discord.Member, duration: int): # 这里的member已经是Member对象了,放心操作roles # 先找到你的封禁角色 suspend_role = get(ctx.guild.roles, name="封禁角色") if not suspend_role: await ctx.send("找不到名为「封禁角色」的角色,请检查配置!") return # 添加封禁角色 await member.add_roles(suspend_role) # 后续的定时移除角色逻辑(记得用asyncio.sleep或者任务调度) await asyncio.sleep(duration) await member.remove_roles(suspend_role)
场景2:手动解析消息内容
如果是通过on_message事件手动处理命令,就得自己把用户提及转换成Member对象:
import asyncio from discord.utils import get @bot.event async def on_message(message): if message.content.startswith('!suspend'): args = message.content.split() if len(args) < 3: await message.channel.send("命令格式错误!请用:`!suspend @用户提及 时长数值`") return # 从提及字符串里提取用户ID(比如<@123456789>,去掉<@!>这些符号) user_id = int(args[1].strip('<@!>')) # 从当前服务器获取Member对象 member = message.guild.get_member(user_id) # 如果本地缓存没有,就从Discord API拉取 if not member: try: member = await message.guild.fetch_member(user_id) except: await message.channel.send("无法找到该用户,请确认对方在当前服务器中!") return # 找到封禁角色 suspend_role = get(message.guild.roles, name="封禁角色") if not suspend_role: await message.channel.send("找不到名为「封禁角色」的角色,请检查!") return # 添加角色 await member.add_roles(suspend_role) # 定时移除 await asyncio.sleep(duration) await member.remove_roles(suspend_role) # 别忘了处理其他命令 await bot.process_commands(message)
小提示
你提到变量hours实际单位是秒,这个命名一定要尽快修正,比如改成duration_seconds或者直接seconds,不然以后维护的时候很容易搞混,踩不必要的坑!
内容的提问来源于stack exchange,提问作者Matthew Kopie
相关产品推荐
相关产品推荐

