万能的字典,可以通过 config.server.port
的方式访问,也可以通过get_config("server.port")
的方式访问,还可以config['server']['port']
访问值
class DotDict(dict):
"""
一个字典类,支持通过点分路径访问和设置嵌套的字典值。
"""
def __init__(self, *args, **kwargs):
"""
初始化DotDict实例,自动将嵌套的字典转换为DotDict实例。
"""
super().__init__(*args, **kwargs)
self._convert_to_dotdict()
def _convert_to_dotdict(self):
"""
递归地将字典值转换为DotDict实例。
"""
for key, value in self.items():
if isinstance(value, dict):
self[key] = DotDict(value)
def __getattr__(self, item):
"""
允许使用属性访问语法来获取字典值。
如果属性不存在,抛出AttributeError异常。
"""
try:
return self.get_config(item)
except KeyError:
raise AttributeError(f"{self.__class__.__name__} object has no attribute '{item}'")
def __setattr__(self, key, value):
"""
允许使用属性赋值语法来设置字典值。
如果键不存在,将创建新的键值对。
"""
self.set_config(key, value)
def get_config(self, path):
"""
通过点分路径获取配置值。
:param path: 配置项的点分路径。
:return: 配置值。
"""
keys = path.split('.')
value = self
for key in keys:
if isinstance(value, dict) and key in value:
value = value[key]
else:
raise KeyError(f"Key '{key}' not found in path '{path}'")
return value
def set_config(self, path, value):
"""
通过点分路径设置配置值。
:param path: 配置项的点分路径。
:param value: 要设置的值。
"""
keys = path.split('.')
target = self
for key in keys[:-1]:
if key not in target or not isinstance(target[key], dict):
target[key] = DotDict()
target = target[key]
target[keys[-1]] = value
测试代码
from core.common.libs.dot_dict import DotDict
configs = {
"server": {
"port": 8080,
"host": "localhost"
},
"database": {
"user": "admin",
"password": "secret",
"host": "localhost",
}
}
# 创建DotDict实例
dot_config = DotDict(configs)
# 使用get_config方法
port = dot_config.get_config("server.port")
password = dot_config.get_config("database.password")
print(port)
print(password)
# 使用set_config方法
dot_config.set_config("server.host", "127.0.0.1")
# 使用 . 出对象的方式获取
print(dot_config.server.host)
# 使用 . 出对象的方式赋值
dot_config.server.path = "/image"
print(dot_config.server.path)
print(dot_config.get_config("server.path"))
# 使用字典的方式获取
print(dot_config['server']['host'])
print(dot_config['server']['port'])
print(dot_config.get_config("server.host"))
# 使用字典的方式赋值
dot_config['server']['aaa'] = "5000"
print(dot_config.server.aaa)
print(dot_config.get_config("server.aaa"))
最后输出