Python开发Discord机器人调用add_role加角色报AttributeError怎么解决
错误产生原因
- 直接原因是
add_role函数中异步方法调用遗漏await:fetch_member()是discord.py的异步方法,必须加await才能拿到实际的Member对象,不加的话返回的是协程对象,对协程对象调用add_roles自然会触发属性不存在的错误。 - 次要问题是参数类型不匹配:
add_role函数的形参要求第二个参数是discord.Member类型、第三个是discord.Role类型,但你在daily_task里传的是用户ID(数值/字符串类型)和角色名字符串,不符合类型要求,就算修复第一个问题也会继续报错。 - 冗余代码问题:
client.get_guild(ctx.guild.id)属于多余操作,直接使用ctx.guild就能拿到当前服务器对象。 - 设计问题:直接调用被
@client.command装饰的命令函数不是最佳实践,命令函数本身是为响应用户消息指令设计的,内部逻辑建议抽成独立公用函数复用。
修复方案
步骤1:抽离独立的公用加角色逻辑
async def add_role_to_member(guild: discord.Guild, user_id: int, role_name: str): # 先获取目标角色对象 target_role = discord.utils.get(guild.roles, name=role_name) if not target_role: raise ValueError(f"未找到名为{role_name}的角色") # 加await获取真实成员对象 try: member = await guild.fetch_member(user_id) except discord.NotFound: raise ValueError(f"ID为{user_id}的用户不在当前服务器") # 加角色 await member.add_roles(target_role)
步骤2:调整原add_role命令函数
@client.command(pass_context=True) @commands.has_permissions(administrator=True) async def add_role(ctx, member: discord.Member, role: discord.Role): await member.add_roles(role)
步骤3:修改daily_task调用逻辑
@client.command() async def daily_task(ctx): try: connectDB() cursor = cnx.cursor(buffered=True) stmt = """very long sql statement""" cursor.execute(stmt) for a, b, c, d, e, f, g ,h ,i, j, k, l in cursor.fetchall(): print(d) #troubleshooting if d != 0: # 把数据库取出的ID转为int类型,传入公用函数 await add_role_to_member(ctx.guild, int(d), "VEP") cursor.close() cnx.close() await ctx.send("每日角色分配任务执行完成") except Exception as e: await ctx.send(f"任务出错:{str(e)}") print(e)
内容的提问来源于stack exchange,提问作者Devon
相关产品推荐
相关产品推荐

