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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:04:16