Discord机器人如何无需重启程序即可实时更新JSON文件数据?
问题根因
翻译映射数据在程序启动时仅从JSON文件加载一次到内存,add_emoji 方法仅将新词条写入磁盘上的JSON文件,没有同步更新内存中存储的字典对象。后续translate 指令调用的does_translation_exist、emojify 函数读取的都是启动时加载的旧内存数据,必须重启程序重新加载文件才能读到新写入的内容,和你猜测的原因一致。
修复方案
方案1:写入文件时同步更新内存字典(推荐,性能最优)
这个方案无需每次执行指令都重复读取磁盘,适合长期24小时运行的部署场景。
- 首先在程序初始化阶段,将JSON中的翻译映射加载为全局可操作的字典对象:
import json # 替换为你的JSON存储文件实际路径 TRANSLATION_FILE = "translations.json" # 启动时加载一次全量数据到内存 with open(TRANSLATION_FILE, "r", encoding="utf-8") as f: translation_map = json.load(f)
- 修改依赖翻译数据的工具函数,直接操作内存中的全局字典:
def does_translation_exist(word): # 直接查内存字典,返回对应翻译或None return translation_map.get(word) def add_emoji(word, emoji): # 第一步先更新内存中的字典 translation_map[word] = emoji # 第二步将最新的全量字典写回磁盘持久化 with open(TRANSLATION_FILE, "w", encoding="utf-8") as f: json.dump(translation_map, f, ensure_ascii=False, indent=2) def emojify(word_tuple): output = [] unknown_words = [] for word in word_tuple: if word in translation_map: output.append(translation_map[word]) else: unknown_words.append(word) return (" ".join(output), unknown_words)
改完后执行!add指令时,内存数据和磁盘文件会同步更新,立刻调用!translate就能识别新增词条,完全不需要重启程序。
方案2:每次操作前重新加载JSON文件(实现简单,适合小数据量)
如果不想调整全局变量结构,直接在所有需要读取翻译数据的逻辑前,重新从磁盘加载JSON即可。先封装统一的加载方法:
def load_translation_map(): with open("translations.json", "r", encoding="utf-8") as f: return json.load(f)
在does_translation_exist、emojify函数的最开头调用该方法,拿到最新的字典数据后再执行后续逻辑:
def does_translation_exist(word): current_map = load_translation_map() return current_map.get(word) def emojify(word_tuple): current_map = load_translation_map() output = [] unknown_words = [] for word in word_tuple: if word in current_map: output.append(current_map[word]) else: unknown_words.append(word) return (" ".join(output), unknown_words)
注意:该方案每次执行指令都会产生一次磁盘IO,翻译词条数量少于1000条时性能差异可以忽略,数据量较大时优先选方案1。
Heroku部署注意
Heroku dyno的本地文件系统是临时存储,每次dyno重启、重新部署时,本地写入的JSON文件会被重置为代码仓库中的初始版本。如果需要长期持久化用户新增的词条,后续需要替换为Heroku提供的PostgreSQL等外置持久化存储服务,避免重启后数据丢失。
内容的提问来源于stack exchange,提问作者dishonestduck
相关产品推荐
相关产品推荐

