YAMLManager 与动态配置系统
在很多老旧的机器人框架里,改个配置就得把整个进程杀掉重启?在 Eridanus 这里可不用这么憋屈哦!
Eridanus 的配置系统基于 framework_common/framework_util/yamlLoader.py 中的 YAMLManager 构建。它不仅将 run/ 下所有零散的 config.yaml 自动聚合为一个面向对象的属性树,还内置了基于 Watchdog 的文件监视器与毫秒级防抖热重载机制。
1. 配置对象的层级访问原理
当主程序调用 config = YAMLManager("run") 时,管理器会递归扫描所有子目录,并将目录名与文件名映射为 Python 对象的属性:
python
# 访问 run/common_config/basic_config.yaml 中的 master.id
master_qq = config.common_config.basic_config["master"]["id"]
# 访问 run/my_awesome_plugin/config.yaml 中的自定义参数
my_api_key = config.my_awesome_plugin.config.get("api_key", "default_val")
# 访问 run/resource_collector/config.yaml 中的 asmr 字段
asmr_level = config.resource_collector.config["asmr"]["asmr_level"]注意层级规则:
- 根属性名称对应于
run/下的子文件夹名称;- 二级属性对应去掉
.yaml后缀的配置文件名(如果目录下只有一个config.yaml,直接用.config访问即可);- 读取到的内容为标准的 Python
dict/list结构。
2. 毫秒级防抖热重载机制 (Watchdog)
yamlLoader.py 内部实现了 YAMLFileHandler:
- 文件变更监听:系统在后台拉起
Observer监视线程,捕获任何.yaml或.yml文件的写盘事件; - 定时器防抖 (0.3s):代码编辑器在保存时往往会产生多次临时写入事件,防抖逻辑确保只在最后一次稳定落盘后的 0.3 秒触发重新解析;
- 线程安全原子替换:在互斥锁保护下重读 YAML,新字典原子替换内存中的旧对象;
- 即刻生效:插件的业务代码下一次读取
config.xxx时,拿到的立刻就是修改后的全新数值,完全无需重启 Python 进程!
3. 插件开发中的最佳配置实践
如果你正在编写一个新插件 run/my_plugin/:
第一步:创建专属 config.yaml
yaml
enable: true
reply_prefix: "【我的插件】"
max_daily_limit: 10
admin_level_required: 100第二步:在插件代码中直接使用注入的 config
python
def main(bot, config):
@bot.on(GroupMessageEvent)
async def handle_msg(event: GroupMessageEvent):
# 实时读取,哪怕你在运行时修改了 config.yaml,这里也会秒级同步最新值!
plugin_cfg = config.my_plugin.config
if not plugin_cfg.get("enable", False):
return
prefix = plugin_cfg.get("reply_prefix", "")
if event.pure_text == "测试":
await bot.send(event, f"{prefix} 收到测试指令喵~")无需手动加载文件,无需处理编码与序列化,开箱即用,优雅丝滑!