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

Discord机器人pay命令执行报错:NoneType不可迭代问题排查

问题:Discord机器人pay命令触发TypeError错误

执行pay命令时触发以下错误:

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: argument of type 'NoneType' is not iterable

原代码

#imports commands from discord.txt
#imports json files
import discord
from discord.ext import commands 
import json
import os

os.chdir("C:\Users\jceze\OneDrive\Desktop\fletch points bot")

intents = discord.Intents.all()

#client variable
client = commands.Bot(command_prefix=">",intents=intents)

client = commands.ext import commands

#On ready event
@client.event
async def on_ready():
    print("Ready")

#checks balance, creates account in mainbank.json
@client.command()
async def balance(ctx):
    await open_account(ctx.author)
    user = ctx.author
    users = await load_bank_data()

    bank_amt = users[str(user.id)]["bank"]

    em = discord.Embed(titele = f"{ctx.author.name}'s balance", color = discord.Color.red())
    em.add_field(name = "Bank", value = bank_amt)
    await ctx.send(embed = em)

@client.command()
async def pay(ctx, amount = None):
    await open_account(ctx.author)
    user = ctx.author
    users = await load_bank_data()

    if amount == None:
        await ctx.send("Please enter the amount")
        return
    else:
        payment = amount
    
    await ctx.send(f"You have been paid {payment} coins!!")

    users[str(user.id)]["bank"] += payment

    with open("mainbank.json","w") as f:
        json.dump(users,f)

#helper function to open user bank
async def open_account(user):
    users = await load_bank_data()
    
    if str(user.id) in users:
        return False
    else:
        users[str(user.id)]["bank"] = 0

    with open("mainbank.json", "w") as f:
        json.dump(users,f)
        return True

#helper function which loads bank data
async def load_bank_data():
    with open("mainbank.json","r") as f:
        users = json.load(f)

#so user can check bank detals
async def update_bank(user , change = 0, mode = "wallet"):
    users = await load_bank_data()

    users[str(user.id)][mode] += change

    with open("mainbank.json","w") as f:
        json.dump(users, f)

    bal = [users[str(user.id)][mode], users[str(user.id)][mode]]
    return user

client.run( "MTAyODAyMzU1NTM0NDA0ODEzOA.GA7kP5.13TjOpz7N7tz0RPaAGbSW4u8bx5B-8rKkGnmDE")

错误原因分析

  1. load_bank_data函数无返回值:该函数读取JSON数据后未返回users变量,调用后得到None,后续open_account中判断str(user.id) in users时,users为None,触发NoneType不可迭代错误。
  2. Client实例被错误覆盖:client = commands.ext import commands是语法错误,直接覆盖了之前创建的commands.Bot实例,导致命令无法正常注册。
  3. 用户账户初始化逻辑错误:open_account中用户不存在时,直接给users[str(user.id)]["bank"]赋值,若users为空字典会触发KeyError,需先创建用户的字典结构。
  4. 金额类型未转换:pay命令中amount是字符串类型,直接与整数相加会触发类型错误,需转为整数。
  5. Embed标题拼写错误:balance命令中discord.Embed(titele=...)的titele应为title。
  6. update_bank函数逻辑错误:返回值应为余额而非用户对象,且余额列表中两个元素重复,未区分钱包和银行。

修复后的完整代码

import discord
from discord.ext import commands 
import json
import os

# 使用原始字符串避免路径转义问题
os.chdir(r"C:\Users\jceze\OneDrive\Desktop\fletch points bot")

intents = discord.Intents.all()
client = commands.Bot(command_prefix=">", intents=intents)

@client.event
async def on_ready():
    print("Ready")

@client.command()
async def balance(ctx):
    await open_account(ctx.author)
    user = ctx.author
    users = await load_bank_data()

    bank_amt = users[str(user.id)]["bank"]
    # 修复Embed标题拼写错误
    em = discord.Embed(title=f"{ctx.author.name}'s balance", color=discord.Color.red())
    em.add_field(name="Bank", value=bank_amt)
    await ctx.send(embed=em)

@client.command()
async def pay(ctx, amount: int = None):
    await open_account(ctx.author)
    user = ctx.author
    users = await load_bank_data()

    if amount is None:
        await ctx.send("Please enter the amount")
        return
    
    # 确保金额为正整数
    if amount <= 0:
        await ctx.send("Amount must be a positive number")
        return

    users[str(user.id)]["bank"] += amount
    await ctx.send(f"You have been paid {amount} coins!!")

    with open("mainbank.json", "w") as f:
        json.dump(users, f)

async def open_account(user):
    users = await load_bank_data()
    user_id = str(user.id)
    
    if user_id in users:
        return False
    else:
        # 正确初始化用户账户结构
        users[user_id] = {"bank": 0}

    with open("mainbank.json", "w") as f:
        json.dump(users, f)
    return True

async def load_bank_data():
    # 处理文件不存在的情况,返回空字典
    try:
        with open("mainbank.json", "r") as f:
            return json.load(f)
    except FileNotFoundError:
        return {}

async def update_bank(user, change=0, mode="bank"):
    users = await load_bank_data()
    user_id = str(user.id)
    
    # 确保用户账户存在
    await open_account(user)
    users[user_id][mode] += change

    with open("mainbank.json", "w") as f:
        json.dump(users, f)

    # 返回正确的银行余额
    return users[user_id]["bank"]

client.run("MTAyODAyMzU1NTM0NDA0ODEzOA.GA7kP5.13TjOpz7N7tz0RPaAGbSW4u8bx5B-8rKkGnmDE")

关键修复点说明

  • 给load_bank_data添加返回值,并处理文件不存在的情况,避免返回None。
  • 删除错误的client = commands.ext import commands语句,保留正确的Bot实例。
  • 修复open_account中用户初始化逻辑,先创建用户字典再赋值银行余额。
  • 在pay命令中指定amount为int类型,添加金额合法性校验。
  • 修正Embed标题的拼写错误。
  • 调整update_bank函数的返回值和逻辑,确保用户账户存在后再修改余额。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:50:20