Discord.py !mute定时禁言命令仅识别时间首位数字问题咨询
问题根因
你的代码中时长计算逻辑存在两处问题:
- 数值提取错误:
tempmute= int(time[0]) * time_convert[time[-1]]里只提取了time字符串的第一个字符作为时长数值,所以只要时间数值超过1位,就只会识别首位数字,才会出现32s识别为3s、12m识别为1m的问题 - 双字符单位兼容错误:你配置的单位字典包含双字符单位
mo,但原有逻辑只取字符串最后一位匹配单位,输入带mo单位的时长时会直接触发KeyError报错
修复方案
你需要先拆分出time参数里的数字部分和单位部分,再进行换算:
- 优先匹配双字符单位
mo,再匹配其他单字符单位 - 提取对应单位之外的所有内容转为整数作为时长数值,再乘以对应换算系数得到总秒数
修复后的完整代码如下:
@commands.has_permissions(manage_messages=True) async def mute(ctx, member: discord.Member, time, reason=None): desctime = time guild = ctx.guild mutedRole = discord.utils.get(guild.roles, name="Muted") time_convert = {"s":1, "m":60, "h":3600, "d":86400, "w":604800, "mo":18144000, "y":31536000} # 修复后的时长计算逻辑 if time.endswith('mo'): # 处理双字符单位mo num = int(time[:-2]) unit = 'mo' else: # 处理单字符单位 num = int(time[:-1]) unit = time[-1] tempmute = num * time_convert[unit] if not mutedRole: mutedRole = await guild.create_role(name="Muted") for channel in guild.channels: await channel.set_permissions(mutedRole, speak=False, send_messages=False, read_message_history=True, read_messages=False) embed = discord.Embed(title="muted", description=f"{member.mention} was muted for {desctime} ", colour=discord.Colour.light_gray()) embed.add_field(name="reason:", value=reason, inline=True) await ctx.send(embed=embed) await member.add_roles(mutedRole, reason=reason) await asyncio.sleep(tempmute) await member.send(f" you have been muted from: {guild.name} reason: {reason}") await member.remove_roles(mutedRole)
额外优化建议
- 可以增加入参校验逻辑,判断输入的
time格式是否符合要求,避免用户输入非法格式时程序报错 - 长时长禁言不建议直接用
asyncio.sleep,机器人重启后计时就会失效,可改用数据库存储禁言到期时间,定时巡检到期的禁言用户自动解除
内容的提问来源于stack exchange,提问作者Legendary CHow
相关产品推荐
相关产品推荐

