discord.py机器人/towers命令报IndexError: list index out of range故障排查
问题修复方案
1. 解决 IndexError: list index out of range 错误
你的grid列表仅包含8个元素(索引范围0-7),但当用户输入的tile_amount大于8时,循环变量count会递增到8,此时访问grid[count]会超出列表索引范围。同时需要限制tile_amount不能小于1,避免无效输入。
修复方式:
方案一:参数级验证
使用app_commands.Range直接限定tile_amount的取值范围为1-8,用户无法输入超出范围的数值:@tree.command(name = 'towers', description='towers gamemode') @app_commands.describe(round_id="8位长度的回合ID", tile_amount="1-8之间的数字") async def towers(interaction: discord.Interaction, round_id:str, tile_amount: app_commands.Range[int, 1, 8]): # 后续逻辑保持不变方案二:函数内判断
在函数开头添加范围检查,不符合条件时返回错误提示:async def towers(interaction: discord.Interaction, round_id:str, tile_amount:int): if not (1 <= tile_amount <= 8): em = discord.Embed(color=0xff0000) em.add_field(name='Error', value="Tile amount must be between 1 and 8") await interaction.response.send_message(embed=em) return # 原有逻辑继续执行
2. 解决闲置后提示无效Round ID的问题
机器人长时间闲置后,Discord的WebSocket连接可能断开重连,而你的代码仅在第一次on_ready时同步命令树,后续重连不会重新同步,导致命令参数解析异常(比如用户输入的round_id未被正确传递,触发长度检查失败)。
修复方式:
修改
on_ready方法,移除self.synced判断,每次机器人就绪时都重新同步命令树:async def on_ready(self): await self.wait_until_ready() await tree.sync() print(f"We have logged in as {self.user}.")可选:添加管理员专用同步命令,方便主动刷新命令缓存:
@tree.command(name="sync", description="同步命令树(仅管理员)") @app_commands.default_permissions(administrator=True) async def sync(interaction: discord.Interaction): await tree.sync() await interaction.response.send_message("命令树已同步", ephemeral=True)
完整修复后的代码示例
import discord from discord import app_commands from random import randint import time class aclient(discord.Client): def __init__(self): super().__init__(intents = discord.Intents.all()) async def on_ready(self): await self.wait_until_ready() await tree.sync() print(f"We have logged in as {self.user}.") client = aclient() tree = app_commands.CommandTree(client) @tree.command(name = 'towers', description='towers gamemode') @app_commands.describe(round_id="输入8位长度的回合ID", tile_amount="选择1-8之间的格子数量") async def towers(interaction: discord.Interaction, round_id:str, tile_amount: app_commands.Range[int, 1, 8]): if len(round_id) != 8: em = discord.Embed(color=0xff0000) em.add_field(name='Error', value="Invalid round id") await interaction.response.send_message(embed=em) return start_time = time.time() # 更简洁的grid初始化方式 grid = [['❓','❓','❓'] for _ in range(8)] count = 0 while count < tile_amount: a = randint(0,2) grid[count][a] = '✅' count += 1 chance = randint(45,95) if tile_amount < 4: chance -= 15 # 简化网格字符串拼接逻辑 grid_str = "\n".join(["".join(row) for row in reversed(grid)]) em = discord.Embed(color=0x0025ff) em.add_field( name="Grid", value=f"```\n{grid_str}\n```" f"**Accuracy**\n```{chance}%```\n" f"**Round ID**\n```{round_id}```\n" f"**Response Time:**\n```{int(time.time() - start_time)}ms```" ) await interaction.response.send_message(embed=em) @tree.command(name="sync", description="同步命令树(仅管理员)") @app_commands.default_permissions(administrator=True) async def sync(interaction: discord.Interaction): await tree.sync() await interaction.response.send_message("命令树已同步", ephemeral=True) client.run('你的机器人Token')
内容的提问来源于stack exchange,提问作者Growdice
相关产品推荐
相关产品推荐

