如何用Python存储多人数据?discord.py机器人积分持久化实现
嘿,我来帮你搞定这个Discord机器人的积分持久化问题!针对你和朋友本地使用的场景,我给你推荐两种简单靠谱的存储方案,直接上手就能用:
解决Discord.py机器人的Brownie Points持久化存储问题
一、选哪种存储方式?
因为是小范围本地使用,不需要复杂的云数据库,优先推荐这两种:
- JSON文件存储:轻量易上手,代码改动最小,完全满足你的需求
- SQLite数据库:Python自带,比JSON更适合结构化数据,如果以后想扩展积分功能(比如加等级、记录历史),用这个更稳
二、JSON文件实现方案(最适合你的场景)
1. 核心思路
把用户的积分数据存在一个JSON文件里,机器人启动时自动加载,每次修改积分后立刻保存到文件,这样重启机器人也不会丢数据。
2. 完整可运行代码
先修正你的导入问题(现在discord.py的规范导入方式如下),直接替换成下面的代码就行:
import discord from discord.ext import commands import json import os # 初始化机器人,设置命令前缀为'!',记得开启所有必要的Intents bot = commands.Bot(command_prefix='!', intents=discord.Intents.all()) # 积分存储文件的路径,会生成在脚本同目录下 POINTS_FILE = "brownie_points.json" # 加载本地积分数据 def load_points(): if os.path.exists(POINTS_FILE): with open(POINTS_FILE, 'r', encoding='utf-8') as f: return json.load(f) # 文件不存在就返回空字典 return {} # 保存积分数据到文件 def save_points(points_data): with open(POINTS_FILE, 'w', encoding='utf-8') as f: json.dump(points_data, f, indent=4, ensure_ascii=False) # 全局变量存储当前所有用户的积分 brownie_points = load_points() # 机器人启动成功的提示 @bot.event async def on_ready(): print(f'已登录为 {bot.user.name},可以开始颁发积分啦!') print('------') # 颁发积分的命令:!give @用户 积分数量 @bot.command(name='give') async def give_points(ctx, member: discord.Member, points: int): # 用*用户ID*作为存储键,避免用户改昵称导致数据丢失 user_id = str(member.id) # 更新积分 if user_id in brownie_points: brownie_points[user_id] += points else: brownie_points[user_id] = points # 立刻保存到文件 save_points(brownie_points) await ctx.send(f'已给 {member.mention} 颁发 {points} 个Brownie Points!当前总积分:{brownie_points[user_id]}') # 查询自己的积分:!points @bot.command(name='points') async def check_my_points(ctx): user_id = str(ctx.author.id) total_points = brownie_points.get(user_id, 0) await ctx.send(f'你的Brownie Points总共有:{total_points}') # 查询他人的积分:!userpoints @用户 @bot.command(name='userpoints') async def check_user_points(ctx, member: discord.Member): user_id = str(member.id) total_points = brownie_points.get(user_id, 0) await ctx.send(f'{member.mention} 的Brownie Points总共有:{total_points}') # 替换成你自己的机器人Token bot.run('YOUR_BOT_TOKEN_HERE')
3. 关键细节提醒
- 一定要用用户ID作为存储键:用户可以随便改昵称,但ID是永久唯一的,能避免数据混乱
- 每次修改积分后立刻调用
save_points:确保数据实时写入文件,哪怕机器人意外重启也不会丢数据 - 启动机器人时自动加载文件:一开机就能读取之前的积分记录
三、SQLite方案(适合未来扩展)
如果以后你们想给积分系统加更多功能(比如记录每次颁发的时间、积分等级),可以用Python自带的SQLite,不需要额外安装软件:
核心代码片段
import sqlite3 # 连接到本地SQLite数据库(文件不存在会自动创建) conn = sqlite3.connect('brownie_points.db') c = conn.cursor() # 创建用户积分表(不存在则创建) c.execute('''CREATE TABLE IF NOT EXISTS points (user_id TEXT PRIMARY KEY, points INTEGER DEFAULT 0)''') conn.commit() # 更新用户积分 def update_points(user_id, add_points): # 先查询当前积分,再加新积分 current = get_points(user_id) new_points = current + add_points c.execute('INSERT OR REPLACE INTO points VALUES (?, ?)', (user_id, new_points)) conn.commit() # 查询用户积分 def get_points(user_id): c.execute('SELECT points FROM points WHERE user_id = ?', (user_id,)) result = c.fetchone() return result[0] if result else 0
之后把之前命令里的读写逻辑换成调用这些函数就行,记得机器人关闭时要执行conn.close()关闭数据库连接。
四、小提示
- 确保机器人在Discord服务器里有发送消息的权限,Intents要在开发者后台开启(代码里用了
Intents.all(),开发测试完全够用) - JSON文件会存在脚本同一目录下,别误删就行;如果是多人同时操作积分,JSON偶尔会有小概率的并发问题,但你们本地用基本不会遇到,真遇到的话换SQLite就解决了
内容的提问来源于stack exchange,提问作者tristan360
相关产品推荐
相关产品推荐

