启动Discord.py机器人遇语法错误:非默认参数尾随默认参数
解决Discord.py机器人命令的SyntaxError问题
你碰到的这个SyntaxError: non-default argument follows default argument错误,根源很明确——函数参数的顺序不符合Python的规则。Python要求没有默认值的参数(也就是调用时必须传值的参数),必须放在有默认值的参数前面,不然解释器会搞不清参数传递的逻辑。
先看你原来的函数定义:
async def role(ctx, member: discord.Member=None,role_time : int, role: discord.Role = None):
这里role_time是没有默认值的参数,却被放在了有默认值的member后面,这就违反了参数顺序的规则,直接触发了语法错误。
另外,你的代码还有几个逻辑和API使用的小问题,我一起帮你修正了,下面是调整后的完整代码:
import asyncio import discord from discord.ext import commands @bot.command() @commands.has_role('new role') async def role(ctx, role_time: int, member: discord.Member=None, role: discord.Role=None): # 先处理未指定成员的情况 if not member: await ctx.send("Who do you want me to give a role?") return # 如果没传入目标角色,默认使用名为"muted"的角色 if not role: role = discord.utils.get(ctx.guild.roles, name="muted") # 额外判断:如果连muted角色都找不到,提示用户 if not role: await ctx.send("Couldn't find the 'muted' role! Please specify a valid role instead.") return # 给成员添加角色并反馈 await member.add_roles(role) await ctx.send(f"Got it! I gave {member.mention} the {role.name} role :thumbsup:") # 等待指定时长后移除角色 await asyncio.sleep(role_time) await member.remove_roles(role) await ctx.send(f"Time's up! The {role.name} role for {member.mention} has been removed.")
主要修改点说明:
- 调整参数顺序:把无默认值的
role_time移到了member和role前面,完全符合Python的参数定义规则,解决了语法错误的核心问题 - 修正逻辑顺序:先判断角色是否为空,再去获取默认的muted角色,避免了原来代码中覆盖传入角色参数的问题
- 替换过时API:把错误的
await self.bot.say改成了Discord.py v1.0+推荐使用的ctx.send方法 - 优化提示信息:用f-string让消息更直观,添加了成员提及和角色名称,用户体验更好
- 增加错误处理:当找不到默认的muted角色时,会主动提示用户,避免程序静默崩溃
最后再强调一下参数顺序的规则:在Python函数定义中,位置参数(无默认值)必须排在关键字参数(有默认值)的前面,这样解释器才能正确识别你传递的参数对应哪个形参。
内容的提问来源于stack exchange,提问作者vinyzu löl
相关产品推荐
相关产品推荐

