You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:52:21