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

为discord.py临时禁言命令添加参数时遇语法错误求助

一、错误原因详解

你遇到的SyntaxError: positional argument follows keyword argument是Python基础语法错误,结合discord.py命令解析规则,主要触发场景有两个:

  1. 参数定义不匹配用户输入:如果reason是普通参数,当用户输入带空格的理由时(比如!mute @小明 10m 刷屏广告),discord.py会把空格后的内容拆分成多个位置参数,导致参数数量超出函数定义,触发解析错误。
  2. 内部函数调用顺序错误:比如创建Embed或调用禁言API时,写了类似await member.timeout(duration, reason="刷屏", ctx.message)的代码——把位置参数放在了关键字参数后面,直接违反Python参数传递规则。
二、正确的tempmute命令实现(带理由参数)

以下是适配discord.py 2.0+版本的完整可运行代码,同时解决语法问题并优化逻辑:

import discord
from discord.ext import commands
from datetime import timedelta

# 初始化机器人,启用消息内容意图
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!", intents=intents)

@bot.command(name="tempmute")
@commands.has_permissions(moderate_members=True)  # 限制仅有权限的用户使用
async def tempmute(ctx, member: discord.Member, time_str: str, *, reason: str = "未提供理由"):
    # 1. 解析时间参数(支持m=分钟、h=小时、d=天)
    try:
        unit = time_str[-1].lower()
        amount = int(time_str[:-1])
        if unit == "m":
            duration = timedelta(minutes=amount)
        elif unit == "h":
            duration = timedelta(hours=amount)
        elif unit == "d":
            duration = timedelta(days=amount)
        else:
            await ctx.send("时间格式错误,请用「数字+单位」,比如10m、1h、1d")
            return
    except ValueError:
        await ctx.send("时间格式错误,请输入有效数字+单位,比如10m")
        return

    # 2. 执行临时禁言操作
    try:
        await member.timeout(duration, reason=reason)
    except discord.Forbidden:
        await ctx.send("我没有权限禁言这个用户!")
        return
    except discord.HTTPException:
        await ctx.send("禁言操作失败,请重试")
        return

    # 3. 发送格式化通知Embed
    embed = discord.Embed(title="临时禁言成功", color=discord.Color.red())
    embed.add_field(name="被禁言用户", value=f"{member.mention}({member.name}#{member.discriminator})", inline=False)
    embed.add_field(name="禁言时长", value=f"{amount}{unit.upper()}", inline=False)
    embed.add_field(name="禁言理由", value=reason, inline=False)
    embed.add_field(name="执行管理员", value=f"{ctx.author.mention}", inline=False)
    embed.set_footer(text=f"用户ID: {member.id}")
    await ctx.send(embed=embed)

# 启动机器人
bot.run("你的机器人Token")
三、关键优化点说明(新手必看)
  • 参数定义的*分隔符:函数里的*, reason: str = "未提供理由"是核心,*用来分隔位置参数和关键字参数,discord.py会自动把time_str之后的所有内容(含空格)拼接成reason的值,解决带空格理由的拆分问题;同时给reason设默认值,用户可省略理由参数。
  • 权限控制:@commands.has_permissions(moderate_members=True)装饰器限制仅拥有「管理成员」权限的用户能使用命令,防止滥用。
  • 时间参数校验:增加格式解析和错误处理,支持常用时间单位,给用户明确的错误提示。
  • 异常捕获:对禁言操作的权限不足、请求失败等情况做捕获处理,避免机器人崩溃,同时反馈明确信息。
  • 美观的Embed通知:用Embed替代纯文本,集中展示禁言关键信息,提升可读性。
四、常见排查点

如果仍遇语法错误,检查:

  1. 所有函数调用中,位置参数必须放在关键字参数前面,比如await ctx.send("消息", embed=embed)是正确的,await ctx.send(embed=embed, "消息")是错误的。
  2. reason参数必须放在*后面,或者用*reason接收可变参数(之后用" ".join(reason)拼接成字符串),前者更规范。

内容的提问来源于stack exchange,提问作者Cerulean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:25:23