HoYoCenter/app/config.py

101 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import json5
import app.env as env
class Config:
"""
配置类,用于加载和管理应用配置。
该类通过读取配置文件并将内容映射到实例属性中,使得配置项可以像访问普通属性一样被访问。
它支持递归加载字典类型的配置项,以及直接加载列表和基本数据类型的配置项。
"""
base_config = {
"theme": "dark",
"init": False
}
def __init__(self):
"""
初始化Config实例从配置文件中加载配置并更新实例属性。
"""
# 加载配置文件并指定编码为utf-8确保中文字符正确解析
self._conf_Dict = json5.load(open(os.path.join(env.dirs.user_config_path, "config.json"), encoding="utf-8"))
self._conf_Dict = self.merge_dicts(self.base_config, self._conf_Dict)
# 设置实例的名称,用于标识配置类型
self.__name__ = "<Standard Dictionary>"
# 更新实例属性,将配置项映射为可直接访问的属性
self.update()
def __getattr__(self, name):
"""
当访问不存在的属性时,尝试从配置字典中获取相应的值。
参数:
name (str): 试图访问的属性名。
返回:
配置字典中的对应值。
异常:
如果配置字典中也没有该属性名则抛出AttributeError。
"""
# 检查配置字典中是否存在该属性名
if name in self._conf_Dict:
return self._conf_Dict[name]
else:
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute '{name}'"
)
def merge_dicts(self, *dict_args):
"""
递归合并多个字典。
参数:
*dict_args: 多个字典参数,按优先级从低到高传递。
default (any, 可选): 默认值,当找不到键时返回此值,默认为 None。
返回:
合并后的字典。
"""
result = {}
for dictionary in dict_args:
for key, value in dictionary.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
# 如果当前键对应的值都是字典,则递归合并
result[key] = self.merge_dicts(result[key], value)
else:
# 否则直接覆盖或设置值
result[key] = value
return result
def update(self):
"""
更新实例属性,将配置字典中的内容映射到实例属性中。
该方法主要处理三种类型的配置项:
1. 字典类型递归创建Config实例并设置属性。
2. 列表类型遍历列表对字典项创建Config实例其他项保持不变。
3. 基本数据类型:直接设置实例属性。
"""
# 遍历配置字典中的所有项
for k, v in self._conf_Dict.items():
# 如果值是字典类型递归创建Config实例
if isinstance(v, dict):
setattr(self, k, Config(v))
# 如果值是列表类型对列表中的字典项创建Config实例
elif isinstance(v, list):
setattr(
self,
k,
[Config(item) if isinstance(item, dict) else item for item in v],
)
# 如果值是基本数据类型,直接设置实例属性
else:
setattr(self, k, v)
def __str__(self):
"""
返回配置字典的字符串表示形式。
返回:
配置字典的字符串形式。
"""
return str(self._conf_Dict)