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

Python开发Discord机器人出现TypeError: 'coroutine' object is not subscriptable报错如何修复

错误原因
  • 核心问题是命名冲突:你编写的士兵训练计算函数名为train,同时注册的Discord命令名也设置为train,导致命令函数内调用train()时,实际调用的是Discord框架生成的命令对象,而非你自己写的计算逻辑。调用命令对象会返回协程实例,你尝试对协程使用['key']下标取值,就触发了TypeError: 'coroutine' object is not subscriptable报错。运行日志里的RuntimeWarning: coroutine 'Command.__call__' was never awaited也印证了这一点。
  • 次要问题:如果你的项目使用的是异步MongoDB驱动(如Motor,适配discord.py异步场景的标准选择),所有数据库操作(find_one、find_one_and_update)都需要加await关键字,否则拿到的也是协程对象,无法正常读取/写入数据。
  • 额外逻辑冗余:代码中重复多次查询同一条用户数据,还存在矛盾的条件判断(已判断用户存在后又判断用户不存在),会浪费数据库性能,也可能触发逻辑异常。
修复代码

1. 重命名计算函数,避免冲突

p_t1 = 1
p_t2 = 8
p_t3 = 20  # training potions of t1,t2,t3
train_pot = 0
# 函数名从train改为calc_train,避免和命令名冲突
def calc_train(troop_count, train_pot, tier, t1, t2, t3):
    if(tier == 1):
        if(troop_count*p_t1 > train_pot):  # checks whether we have enough training costs for training t1
            result = "Not enough training potions"
            return result
        else:
            train_pot = train_pot-troop_count*p_t1  # if yes train the tier 1 troops
            t1 += troop_count
            result = {
                'training_train_pot': train_pot,
                'tier1': t1,
                'tier2': t2,
                'tier3': t3
            }
            return result
    elif(tier == 2):
        if(troop_count*p_t2 > train_pot):  # checks whether we have enough training costs for training t2
            result = "Not enough training potions"
            return result
        else:  # if yes train the tier 2 troops
            train_pot = train_pot-troop_count*p_t2
            t2 += troop_count
            result = {
                'training_train_pot': train_pot,
                'tier1': t1,
                'tier2': t2,
                'tier3': t3
            }
            return result
    elif(tier == 3):  # checks whether we have enough training costs for training t3
        if(troop_count*p_t3 > train_pot):
            result = "Not enough training potions"
            return result
        else:  # if yes train the tier 3 troops
            train_pot = train_pot-troop_count*p_t3
            t3 += troop_count
            result = {
                'training_train_pot': train_pot,
                'tier1': t1,
                'tier2': t2,
                'tier3': t3
            }
            return result
    else:
        # if we gave invalid tier print no such tier exist
        result = "No such tier troops exist"
        return result

2. 修正训练命令代码

@bot.command(name="train")  # Training the soldiers
# tier -  troop tier to train, Amount - No. of troops to train
async def training(ctx: commands.Context, tier: int = None, amount: int = None):
    ''' Used to train troops `?train <tier> <troops_amount>` Eg: ||?train 3 100||'''
    if tier is None or amount is None:
        await ctx.send("Give the argument correctly like `?train <tier> <troops_amount>`")
        return
    # 只查询一次用户数据,加await适配异步驱动
    user_data = await user_info.find_one({'id': ctx.author.id})
    if not user_data:
        await ctx.reply('Please start using `?start` command')
        return
    filtr = {'id': ctx.author.id}
    # 调用重命名后的计算函数
    res = calc_train(amount, user_data['potions'], tier,
                user_data['t1'], user_data['t2'], user_data['t3'])
    if res == "Not enough training potions":
        await ctx.send(f'{ctx.author.mention}You dont have enough potions')
    elif res == "No such tier troops exist":
        await ctx.send(f'{ctx.author.mention}No such tier exists. Tiers available are 1-3')
    else:
        # 数据库更新操作加await
        await user_info.find_one_and_update(filtr, {'$set': {
            't1': res['tier1'], 't2': res['tier2'], 't3': res['tier3'], 'potions': res['training_train_pot']}})
        await ctx.send(f"{ctx.author.mention}You have successfully trained {amount} tier {tier} troops")

内容的提问来源于stack exchange,提问作者Daniel Jebarson K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:18:03