一个简单的配置管理工具(A simple dictionary configuration management tool),dict <-> config file [json, toml, yaml, ini, xml]
Project description
ConfuLL
一个轻量级、功能强大的多格式配置管理工具
ConfuLL 让配置管理变得简单直观。它支持 dict 与 json/toml/yaml/ini/xml 之间的无缝转换,提供属性访问、点路径操作、自动保存、加密保护等丰富功能。
目录
安装方法
使用 pip 安装(推荐)
pip install confull
从源码安装
git clone https://github.com/zisull/confull.git
cd confull
pip install .
依赖说明
| 依赖包 | 版本要求 | 用途 |
|---|---|---|
| orjson | >=3.10 | JSON 高性能序列化 |
| toml | >=0.10 | TOML 格式支持 |
| PyYAML | >=6.0 | YAML 格式支持 |
| watchdog | >=3.0 | 文件监听(可选) |
| portalocker | >=3.0 | 进程锁(可选) |
| cryptography | >=42.0 | 加密功能(可选) |
概述
ConfuLL 是一个 Python 配置管理库,核心设计理念是简单易用。
核心概念
from confull import Config
# 创建配置 - 就是这么简单
cfg = Config('app.toml')
# 像使用字典一样使用
cfg.name = "MyApp"
cfg.version = "1.0.0"
# 支持点路径访问嵌套配置
cfg.set('database.host', 'localhost')
cfg.set('database.port', 3306)
# 自动保存,无需手动调用
支持的配置格式
| 格式 | 扩展名 | 特点 |
|---|---|---|
| TOML | .toml | 人类友好,推荐使用 |
| JSON | .json | 通用性强 |
| YAML | .yaml/.yml | 层次清晰 |
| INI | .ini | 简单配置 |
| XML | .xml | 结构化数据 |
特性优点
🚀 轻量简洁
- 零配置开箱即用
- 自动推断文件格式
- 自动创建目录和文件
💡 多种访问方式
# 属性方式
cfg.name = "app"
# 字典方式
cfg['name'] = "app"
# 点路径方式
cfg.set('db.host', 'localhost')
# 链式操作
cfg.set('db.host', 'localhost').set('db.port', 3306)
🔒 安全可靠
- 线程安全(RLock)
- 进程安全可选(portalocker)
- 加密存储(Fernet + PBKDF2)
- 原子写入(临时文件替换)
📁 文件监听
cfg = Config('config.toml')
cfg.enable_watch() # 外部修改后自动重载
🔄 自动保存
- 默认开启自动保存
- 支持去抖延迟(防止频繁写入)
- 程序退出时确保写盘
🎯 键名冲突保护
cfg = Config({'save': True, 'path': '/tmp'})
# cfg.save # ❌ 会调用 save() 方法
cfg.opt.save # ✅ 安全访问冲突键
注意事项
1. 键名冲突
以下名称为保留关键字,不能直接作为顶层配置键:
| 保留名 | 说明 |
|---|---|
to_dict |
转换为字典 |
to_json |
转换为 JSON |
save |
保存配置 |
load |
加载配置 |
reload |
重新加载 |
get |
获取值 |
set |
设置值 |
del_clean |
清空配置 |
opt |
安全访问接口 |
解决方案:
# 使用 opt 属性访问
cfg.opt.save = True
cfg.opt.path = '/tmp'
# 或者放到子节点中
cfg.app.save = True
2. 自动保存行为
默认情况下,任何修改都会自动保存到文件。如需批量操作:
# 方法1:关闭自动保存
cfg = Config('app.toml', auto_save=False)
# ... 批量操作 ...
cfg.save() # 手动保存
# 方法2:使用上下文管理器
with Config('app.toml', auto_save=False) as cfg:
cfg.name = "app"
cfg.version = "1.0"
# 退出时自动保存
# 方法3:使用去抖延迟
cfg = Config('app.toml', debounce_ms=100) # 100ms 内只保存一次
3. 加密配置
- 密码丢失将无法恢复数据
- 修改密码需要先用旧密码读取,再用新密码保存
- 加密文件被篡改会触发校验错误
4. 文件格式推断
# 自动推断
Config('app.toml') # TOML 格式
Config('app.json') # JSON 格式
Config('app') # 默认 TOML
# 显式指定(优先级更高)
Config('data.txt', way='toml') # 使用 TOML 格式读写 .txt 文件
常见用法举例
基础用法
from confull import Config
# 创建配置
cfg = Config('app.toml')
# 设置值
cfg.name = "MyApp"
cfg.version = "1.0.0"
cfg.debug = False
# 获取值
print(cfg.name) # "MyApp"
print(cfg.version) # "1.0.0"
# 删除值
del cfg.debug
嵌套配置
# 创建嵌套结构
cfg.set('database.host', 'localhost')
cfg.set('database.port', 3306)
cfg.set('database.user', 'root')
cfg.set('database.password', 'secret')
# 访问嵌套值
print(cfg.database.host) # "localhost"
print(cfg.get('database.port')) # 3306
# 使用点路径删除
cfg.del_key('database.password')
批量操作
# 批量更新
cfg.update({
'app.name': 'MyApp',
'app.version': '2.0.0',
'debug': True
})
# 完全替换数据
cfg.set_data({
'name': 'NewApp',
'version': '3.0.0'
})
加密配置
# 创建加密配置
cfg = Config('secure.toml', pwd='my-secret-password')
cfg.token = "abc123"
cfg.api_key = "sk-xxxx"
# 读取加密配置(需要密码)
cfg = Config('secure.toml', pwd='my-secret-password')
print(cfg.token) # "abc123"
# 错误密码会抛出异常
cfg = Config('secure.toml', pwd='wrong') # ValueError
文件监听
cfg = Config('config.toml')
cfg.enable_watch()
# 当 config.toml 被外部修改时,cfg 会自动重载
# ...
cfg.disable_watch() # 关闭监听
另存为其他格式
cfg = Config('app.toml')
cfg.to_file('app.json', way='json')
cfg.to_file('app.yaml', way='yaml')
cfg.to_file('backup.txt', way='toml')
核心方法简介
读写操作
| 方法 | 说明 | 返回值 |
|---|---|---|
get(key, default) |
获取配置值 | 值或默认值 |
set(key, value) |
设置配置值 | Config(支持链式) |
setdefault(key, value) |
设置默认值(不存在时) | 最终值 |
first(*keys, default) |
获取第一个存在的键值 | 值或默认值 |
require(key) |
获取必需配置项 | 值(不存在则报错) |
批量操作
| 方法 | 说明 |
|---|---|
update(dict) |
批量更新 |
set_data(dict) |
完全替换 |
merge(other, strategy) |
合并配置 |
删除操作
| 方法 | 说明 |
|---|---|
del_key(key) |
删除指定键(支持点路径) |
del_clean() |
清空并删除配置文件 |
文件操作
| 方法 | 说明 |
|---|---|
save() |
保存到文件 |
reload() |
从文件重新加载 |
to_file(file, way) |
另存为其他文件/格式 |
导入导出
| 方法 | 说明 |
|---|---|
to_dict() |
导出为字典 |
to_json(indent) |
导出为 JSON 字符串 |
to_env(prefix) |
导出为环境变量格式 |
from_env(prefix) |
从环境变量导入 |
比较操作
| 方法 | 说明 |
|---|---|
diff(other) |
比较两个配置的差异 |
监听操作
| 方法 | 说明 |
|---|---|
enable_watch() |
开启文件监听 |
disable_watch() |
关闭文件监听 |
状态查询
| 方法 | 说明 |
|---|---|
path() |
获取文件路径(相对) |
path_abs() |
获取文件路径(绝对) |
is_auto_save() |
是否自动保存 |
set_auto_save(flag) |
设置自动保存 |
详细函数用法及预期效果
1. 初始化 __init__
Config(
data=None, # 初始数据(dict)
file="config", # 文件名(可无扩展名)
way="", # 格式(json/toml/yaml/ini/xml)
replace=False, # 是否覆盖已有文件
auto_save=True, # 是否自动保存
pwd=None, # 加密密码
process_safe=False, # 是否进程安全
debounce_ms=0 # 去抖延迟(毫秒)
)
示例:
# 最简用法
cfg = Config()
# 指定文件
cfg = Config('app.toml')
# 带初始数据
cfg = Config({'name': 'app', 'version': '1.0'}, file='app.toml')
# 加密配置
cfg = Config('secure.toml', pwd='secret')
# 进程安全 + 去抖
cfg = Config('shared.toml', process_safe=True, debounce_ms=100)
预期效果:
- 自动创建目录和文件
- 自动推断格式(根据扩展名)
- 程序退出时自动保存
2. 获取值 get
get(key: str, default: Any = None) -> Any
示例:
cfg = Config({'db': {'host': 'localhost', 'port': 3306}})
# 获取简单值
cfg.get('db') # {'host': 'localhost', 'port': 3306}
# 获取嵌套值(点路径)
cfg.get('db.host') # 'localhost'
cfg.get('db.port') # 3306
# 带默认值
cfg.get('db.user', 'root') # 'root'
cfg.get('cache.enabled') # None
3. 设置值 set
set(key: str, value: Any, overwrite_mode: bool = False) -> Config
示例:
cfg = Config()
# 设置简单值
cfg.set('name', 'MyApp')
# 设置嵌套值(自动创建中间节点)
cfg.set('db.host', 'localhost')
cfg.set('db.port', 3306)
# 链式操作
cfg.set('app.name', 'MyApp').set('app.version', '1.0').set('debug', True)
# 覆盖模式(当类型冲突时)
cfg.set('config', 'old') # 叶子节点
cfg.set('config.key', 'value', overwrite_mode=True) # 转为字典
预期效果:
- 自动保存到文件
- 返回 self 支持链式操作
- 类型冲突时需要
overwrite_mode=True
4. 设置默认值 setdefault
setdefault(key: str, value: Any) -> Any
示例:
cfg = Config({'version': '1.0.0'})
cfg.setdefault('version', '2.0.0') # 返回 '1.0.0'(已存在,不覆盖)
cfg.setdefault('name', 'MyApp') # 返回 'MyApp'(不存在,设置)
预期效果:
- 键存在时返回原值,不修改
- 键不存在时设置新值并返回
5. 获取第一个存在的键 first
first(*keys, default=None) -> Any
示例:
cfg = Config({'host': 'localhost', 'server_host': '127.0.0.1'})
# 按优先级查找
cfg.first('server_host', 'host', 'db.host')
# 返回 '127.0.0.1'(第一个存在的键)
cfg.first('missing', 'host', default='0.0.0.0')
# 返回 'localhost'
cfg.first('a', 'b', 'c', default='none')
# 返回 'none'(都不存在)
预期效果:
- 返回第一个存在且非 None 的值
- 所有键都不存在时返回 default
6. 获取必需配置 require
require(key: str) -> Any
示例:
cfg = Config({'database_url': 'sqlite:///db.sqlite'})
cfg.require('database_url') # 返回 'sqlite:///db.sqlite'
cfg.require('api_key') # 抛出 KeyError: "必需的配置项 'api_key' 不存在或值为 None"
预期效果:
- 存在时返回值
- 不存在或值为 None 时抛出 KeyError
7. 批量更新 update
update(data: Dict[str, Any]) -> None
示例:
cfg = Config({'app': {'name': 'old'}})
cfg.update({
'app.name': 'new',
'app.version': '1.0',
'debug': True
})
print(cfg.app.name) # 'new'
print(cfg.app.version) # '1.0'
print(cfg.debug) # True
预期效果:
- 支持点路径键名
- 合并到现有配置
8. 完全替换 set_data
set_data(data: Dict[str, Any]) -> None
示例:
cfg = Config({'old': 'data'})
cfg.set_data({
'new': 'data',
'version': '2.0'
})
print(cfg.to_dict()) # {'new': 'data', 'version': '2.0'}
预期效果:
- 完全替换现有数据
- 旧数据丢失
9. 合并配置 merge
merge(other: Union[Dict, Config], strategy: str = "override") -> Config
策略说明:
override:覆盖已有值(默认)keep:保留已有值deep:深度合并嵌套字典
示例:
cfg = Config({'db': {'host': 'localhost', 'port': 3306}})
# override 策略
cfg.merge({'db': {'host': '127.0.0.1'}, 'debug': True}, strategy='override')
# {'db': {'host': '127.0.0.1'}, 'debug': True}
# keep 策略
cfg = Config({'db': {'host': 'localhost'}})
cfg.merge({'db': {'host': '127.0.0.1'}, 'debug': True}, strategy='keep')
# {'db': {'host': 'localhost'}, 'debug': True} # host 保留原值
# deep 策略
cfg = Config({'db': {'host': 'localhost', 'port': 3306}})
cfg.merge({'db': {'user': 'root'}, 'debug': True}, strategy='deep')
# {'db': {'host': 'localhost', 'port': 3306, 'user': 'root'}, 'debug': True}
预期效果:
- 返回 self 支持链式操作
- 根据策略决定如何合并
10. 比较差异 diff
diff(other: Union[Dict, Config]) -> Dict[str, Any]
示例:
cfg1 = Config({'a': 1, 'b': 2, 'c': 3})
cfg2 = Config({'a': 1, 'b': 99, 'd': 4})
diff = cfg1.diff(cfg2)
# {
# 'added': {'d': 4},
# 'removed': {'c': 3},
# 'modified': {'b': {'old': 2, 'new': 99}}
# }
预期效果:
- 返回包含
added、removed、modified的字典 - 支持嵌套字典比较
11. 删除键 del_key
del_key(key: str) -> None
示例:
cfg = Config({'a': {'b': {'c': 1, 'd': 2}}, 'e': 3})
cfg.del_key('a.b.c')
# {'a': {'b': {'d': 2}}, 'e': 3} # 自动清理空的父节点
cfg.del_key('e')
# {'a': {'b': {'d': 2}}}
预期效果:
- 支持点路径
- 自动清理空的父节点
12. 清空配置 del_clean
del_clean() -> bool
示例:
cfg = Config({'name': 'app'}, file='app.toml')
cfg.del_clean()
# 配置文件被删除,内存清空
预期效果:
- 删除配置文件
- 清空内存数据
- 返回是否成功
13. 保存 save
save() -> None
示例:
cfg = Config('app.toml', auto_save=False)
cfg.name = 'app'
cfg.save() # 手动保存
预期效果:
- 立即保存到文件
- 忽略去抖延迟
14. 重新加载 reload
reload() -> None
示例:
cfg = Config('app.toml')
# 外部修改了 app.toml
cfg.reload() # 重新加载
预期效果:
- 从磁盘重新加载
- 丢弃未保存的更改
15. 另存为 to_file
to_file(file: str = None, way: str = None) -> None
示例:
cfg = Config({'name': 'app'}, file='app.toml')
cfg.to_file('backup.json', way='json')
cfg.to_file('backup.yaml', way='yaml')
预期效果:
- 保存到指定文件
- 可以转换格式
16. 导出为字典 to_dict
to_dict() -> Dict[str, Any]
示例:
cfg = Config({'db': {'host': 'localhost', 'port': 3306}})
data = cfg.to_dict()
# {'db': {'host': 'localhost', 'port': 3306}}
预期效果:
- 返回深拷贝的原生字典
- 修改不影响原配置
17. 导出为 JSON to_json
to_json(indent: int = 2) -> str
示例:
cfg = Config({'name': 'app', 'version': '1.0'})
print(cfg.to_json())
# {
# "name": "app",
# "version": "1.0"
# }
print(cfg.to_json(indent=4))
# 更多缩进
预期效果:
- 返回 JSON 字符串
- 可自定义缩进
18. 导出为环境变量 to_env
to_env(prefix: str = "", uppercase: bool = True) -> Dict[str, str]
示例:
cfg = Config({'db': {'host': 'localhost', 'port': 3306}})
env = cfg.to_env()
# {'DB_HOST': 'localhost', 'DB_PORT': '3306'}
env = cfg.to_env(prefix='APP')
# {'APP_DB_HOST': 'localhost', 'APP_DB_PORT': '3306'}
env = cfg.to_env(uppercase=False)
# {'db_host': 'localhost', 'db_port': '3306'}
预期效果:
- 嵌套键用下划线连接
- 可添加前缀
- 可控制大小写
19. 从环境变量导入 from_env
from_env(prefix: str = "", separator: str = "_") -> Config
示例:
import os
os.environ['APP_DB_HOST'] = 'localhost'
os.environ['APP_DB_PORT'] = '3306'
cfg = Config()
cfg.from_env(prefix='APP')
print(cfg.db.host) # 'localhost'
print(cfg.db.port) # '3306'
预期效果:
- 只导入指定前缀的变量
- 自动转换为小写
- 自动创建嵌套结构
20. 开启文件监听 enable_watch
enable_watch() -> None
示例:
cfg = Config('config.toml')
cfg.enable_watch()
# 当 config.toml 被外部修改时,cfg 会自动 reload()
cfg.disable_watch() # 关闭监听
预期效果:
- 监听文件变化
- 自动重新加载
21. 安全访问接口 opt
@property
opt -> _DataProxy
示例:
cfg = Config({'save': True, 'path': '/tmp'})
# cfg.save # ❌ 调用的是 save() 方法
cfg.opt.save # ✅ 访问 'save' 配置项
cfg.opt.path = '/var' # ✅ 安全修改
预期效果:
- 避免与方法名冲突
- 支持属性和字典方式访问
22. 属性访问(魔法方法)
# 支持的魔法方法
cfg.key # __getattr__
cfg.key = value # __setattr__
del cfg.key # __delattr__
cfg['key'] # __getitem__
cfg['key'] = val # __setitem__
del cfg['key'] # __delitem__
len(cfg) # __len__
iter(cfg) # __iter__
'key' in cfg # __contains__
bool(cfg) # __bool__
cfg('key') # __call__ 等价于 cfg.get('key')
示例:
cfg = Config({'a': 1, 'b': {'c': 2}})
# 属性访问
cfg.a # 1
cfg.b.c # 2
# 字典访问
cfg['a'] # 1
cfg['b.c'] # 2(支持点路径)
# 长度
len(cfg) # 2
# 迭代
for key in cfg:
print(key)
# 包含判断
'a' in cfg # True
'b.c' in cfg # True(支持点路径)
# 调用方式
cfg('a') # 1
cfg('b.c') # 2
23. 上下文管理器
__enter__() -> Config
__exit__() -> None # 自动保存
示例:
with Config('app.toml', auto_save=False) as cfg:
cfg.name = 'app'
cfg.version = '1.0'
# 退出时自动保存
高级用法及技巧
技巧 1:使用 .txt 文件存储配置
# 用 toml 格式读写 .txt 文件,方便编辑器打开
cfg = Config('config.txt', way='toml')
cfg.name = 'app'
# 文件内容是 toml 格式,但扩展名是 .txt
技巧 2:批量操作优化
# 关闭自动保存,批量操作后手动保存
with Config('large.toml', auto_save=False) as cfg:
for i in range(1000):
cfg.set(f'item.{i}', f'value_{i}')
# 退出时一次性保存
技巧 3:配置合并
# 默认配置 + 用户配置
default_cfg = Config('default.toml')
user_cfg = Config('user.toml')
# 用户配置覆盖默认配置
default_cfg.merge(user_cfg, strategy='deep')
技巧 4:配置模板
# 创建模板
template = {
'app': {
'name': 'MyApp',
'version': '1.0.0',
'debug': False
},
'database': {
'host': 'localhost',
'port': 3306,
'name': 'mydb'
}
}
# 基于模板创建配置
cfg = Config(template, file='app.toml')
技巧 5:环境变量覆盖
# 基础配置
cfg = Config('app.toml')
# 环境变量覆盖(优先级更高)
cfg.from_env(prefix='APP')
技巧 6:配置加密 + 去抖
# 安全配置,100ms 去抖
cfg = Config(
'secure.toml',
pwd='my-secret-key',
debounce_ms=100
)
技巧 7:多进程共享配置
# 进程安全模式
cfg = Config('shared.toml', process_safe=True)
技巧 8:配置版本管理
# 读取配置
cfg = Config('config.toml')
# 修改前备份
cfg.to_file('config.backup.toml')
# 修改配置
cfg.version = '2.0.0'
技巧 9:链式操作
cfg = Config('app.toml')
# 链式设置
cfg.set('db.host', 'localhost') \
.set('db.port', 3306) \
.set('db.user', 'root') \
.set('db.password', 'secret')
# 链式合并
cfg.merge({'cache': {'enabled': True}}) \
.merge({'logging': {'level': 'INFO'}})
技巧 10:配置校验
cfg = Config('app.toml')
# 使用 require 确保必需配置存在
db_url = cfg.require('database.url')
api_key = cfg.require('api.key')
# 使用 setdefault 设置默认值
cfg.setdefault('debug', False)
cfg.setdefault('log_level', 'INFO')
技巧 11:配置差异比较
# 比较两个版本的配置
old_cfg = Config('config.old.toml')
new_cfg = Config('config.new.toml')
diff = old_cfg.diff(new_cfg)
if diff['modified']:
print("修改的配置:")
for key, change in diff['modified'].items():
print(f" {key}: {change['old']} -> {change['new']}")
技巧 12:导出为环境变量
cfg = Config('app.toml')
# 导出为 Docker 环境变量格式
env_vars = cfg.to_env(prefix='MYAPP')
for key, value in env_vars.items():
print(f"{key}={value}")
许可证
MIT License
贡献
欢迎提交 Issue 和 Pull Request!
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file confull-0.1.0.tar.gz.
File metadata
- Download URL: confull-0.1.0.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99e69b30fd9fab40fb83545c08dbb429a7a41fcc58301d10780a3c444e6a50b4
|
|
| MD5 |
8c2b5cfc900c88610b799018b1fb620c
|
|
| BLAKE2b-256 |
7efafb0bed5b441f5cdc1a97057a8a71376739d2be8280943eb469f94b7d9ebd
|
File details
Details for the file confull-0.1.0-py3-none-any.whl.
File metadata
- Download URL: confull-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
008adcf91f5f4a58bc977e5988d4d229624b4b358398729fda42f59618cde8b4
|
|
| MD5 |
6fb2242669ba217a42dff23c723f7a64
|
|
| BLAKE2b-256 |
1bf6dc169bfc8a846ad31b748b79daec316b16ac94a652bf7ae2d6596360543c
|