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")
错误原因分析
load_bank_data函数无返回值:该函数读取JSON数据后未返回users变量,调用后得到None,后续open_account中判断str(user.id) in users时,users为None,触发NoneType不可迭代错误。- Client实例被错误覆盖:
client = commands.ext import commands是语法错误,直接覆盖了之前创建的commands.Bot实例,导致命令无法正常注册。 - 用户账户初始化逻辑错误:
open_account中用户不存在时,直接给users[str(user.id)]["bank"]赋值,若users为空字典会触发KeyError,需先创建用户的字典结构。 - 金额类型未转换:
pay命令中amount是字符串类型,直接与整数相加会触发类型错误,需转为整数。 - Embed标题拼写错误:
balance命令中discord.Embed(titele=...)的titele应为title。 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
相关产品推荐
相关产品推荐

