Nextcord机器人@commands.has_any_role装饰器AttributeError问题求助
你遇到的AttributeError核心原因是变量名冲突:
你从nextcord.ext导入了commands模块,但之后又定义了一个名为commands的命令函数:
@bot.command(name='commands') async def commands(ctx): await helpCommand(True)
这个函数定义会直接覆盖掉之前导入的commands模块引用——在这之后,代码里的commands不再指向nextcord.ext.commands模块,而是指向这个Command对象实例。而Command对象并没有has_any_role属性,所以当你在第79行使用@commands.has_any_role时,自然会触发报错。
而第57行的装饰器能正常工作,是因为它定义在commands函数之前,此时commands还指向原始的模块,所以可以正常访问has_any_role装饰器。
另外,你的commands函数里还有一个小问题:调用helpCommand(True)时没有传递ctx参数,这会导致后续执行helpCommand时出错,因为它的第一个参数需要接收上下文对象。
1. 重命名冲突的函数
把你的commands命令函数改个名字,避免和导入的模块名重复,比如改成show_commands:
@bot.command(name='commands') async def show_commands(ctx): await helpCommand(ctx, fromcommands=True) # 同时修正参数传递,传入ctx
2. 修正装饰器顺序(可选但推荐)
虽然这不是本次报错的直接原因,但Nextcord命令的权限装饰器正确的顺序应该放在@bot.command()的上方(Python装饰器是从下往上执行的,权限检查需要先绑定到函数上,再被@bot.command()包装成Command对象)。
比如把你的crvchannel命令修改为:
@commands.has_any_role("That common coder", "The creator") @bot.command( name='crvchannel', description='This is a command for admins to create voice channels') async def create_voice(ctx, channel_name='default-bot-vc-name'): guild = ctx.guild existing_channel = nextcord.utils.get(guild.channels, name=channel_name) if not existing_channel: print(f'This channel: {channel_name} has been created') await guild.create_voice_channel(channel_name)
3. 额外修复:helpCommand的逻辑问题
你的helpCommand里的fromcommands参数处理逻辑有问题,if fromcommands(False):这种写法是错误的,应该直接判断参数值:
@bot.command(name='helpc') async def helpCommand(ctx, *, fromcommands=False): status = 'did' if fromcommands else 'did not' print( f'{ctx.message.author} asked for help and {status} come from the /commands command.' ) await ctx.send("这里可以添加你的机器人帮助内容") # 原代码里await ctx.send()没有内容,会报错,建议补充
# ... 其他导入和初始化代码不变 ... @bot.command(name='helpc') async def helpCommand(ctx, *, fromcommands=False): status = 'did' if fromcommands else 'did not' print( f'{ctx.message.author} asked for help and {status} come from the /commands command.' ) await ctx.send("这是帮助信息,你可以在这里添加各命令的使用说明") #/////////////////////////////////////////////////////////// @commands.has_any_role('That_common_coder', 'The creator') @bot.command(name='crtchannel', description='This is a command for admins to create text channels' ) async def create_text(ctx, channel_name='default-bot-name'): guild = ctx.guild existing_channel = nextcord.utils.get(guild.channels, name=channel_name) if not existing_channel: print(f'The {channel_name} channel has been created') await guild.create_text_channel(channel_name) #////////////////////////////// @bot.command(name='commands') async def show_commands(ctx): await helpCommand(ctx, fromcommands=True) #/////////////////////////////////////////////////////////// @commands.has_any_role("That common coder", "The creator") @bot.command( name='crvchannel', description='This is a command for admins to create voice channels') async def create_voice(ctx, channel_name='default-bot-vc-name'): guild = ctx.guild existing_channel = nextcord.utils.get(guild.channels, name=channel_name) if not existing_channel: print(f'This channel: {channel_name} has been created') await guild.create_voice_channel(channel_name) # ... 其他代码不变 ...
内容的提问来源于stack exchange,提问作者that_common_coder

