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

Discord卡牌收集机器人Python IndexError索引越界问题求助

问题排查与修复方案

核心错误原因

你代码里的random.choices(cardPathList, cardRarity)没有指定k=3参数,该函数默认仅返回1个元素,导致cardsToDrop列表长度为1,后续访问cardsToDrop[1]和cardsToDrop[2]时触发IndexError。

分步修复

1. 修复随机选卡逻辑

修改random.choices调用,明确指定k=3,确保返回3张卡牌:

cardsToDrop = random.choices(cardPathList, weights=cardRarity, k=3)

注意:random.choices的第二个参数是weights(权重),建议显式命名参数,避免歧义。

2. 处理卡牌数量不足的边界情况

如果数据库中Cards表的卡牌总数少于3张,当前的while True循环会无限执行,因为永远无法选出3张不重复的卡牌。需要添加前置判断:

cardPathList = await query("SELECT filename FROM Cards ORDER BY cardname", cardDBCommand)
if len(cardPathList) < 3:
    await ctx.send("数据库中卡牌数量不足3张,无法执行drop操作!")
    return

3. 修复SQL注入风险(重要)

当前用f-string拼接SQL语句存在严重的SQL注入漏洞,必须改用参数化查询。以获取卡牌名称的语句为例:

# 替换原有的cardNames查询语句
sql = "SELECT cardname FROM Cards WHERE filename IN (?, ?, ?)"
cardNames = await query(sql, cardDBCommand, params=(cardsToDrop[0], cardsToDrop[1], cardsToDrop[2]))

注意:需要确认你的query函数支持接收params参数来处理参数化查询,如果不支持,需根据使用的数据库驱动(如sqlite3、asyncpg等)调整参数传递方式。

4. 其他潜在问题修复

  • 代码中UPDATE Users SET lastgrab = ...是笔误,应改为lastdrop,和数据库字段名保持一致。
  • 重复的用户判断逻辑可简化,减少冗余SQL查询。

修复后的核心代码片段

# ... 前面的用户逻辑 ...
    
cardPathList = await query("SELECT filename FROM Cards ORDER BY cardname", cardDBCommand)
if len(cardPathList) < 3:
    await ctx.send("数据库中卡牌数量不足3张,无法执行drop操作!")
    return

cardRarity = await query("SELECT rarity FROM Cards ORDER BY cardname", cardDBCommand)
cardsToDrop = []
while True:
    cardsToDrop = random.choices(cardPathList, weights=cardRarity, k=3)
    if len(set(cardsToDrop)) == 3:
        break

# 参数化查询获取卡牌名称
sql = "SELECT cardname FROM Cards WHERE filename IN (?, ?, ?)"
cardNames = await query(sql, cardDBCommand, params=(cardsToDrop[0], cardsToDrop[1], cardsToDrop[2]))
imageCreation(cardsToDrop, GREY, os.path.abspath("Temp/drop.png"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:20:35