在Windows Python开发中,配置文件管理是每个开发者都会遇到的问题。是否还在为硬编码的配置信息而苦恼?是否想要一个既灵活又易于维护的配置方案?
JSON配置文件凭借其轻量级、可读性强、跨平台兼容的特点,已成为现代Python应用的首选配置格式。无论是桌面应用、Web服务还是上位机开发,掌握JSON配置文件的读写技巧都是必备技能。
本文将从实际开发场景出发,详细讲解Python读写JSON配置文件的各种方法和最佳实践,帮助你构建更加专业和可维护的应用程序。
在Python开发中,常见的配置文件格式有:
一个良好的JSON配置文件应该具备以下特征:
JSON{
"app_info": {
"name": "MyPythonApp",
"version": "1.0.0",
"author": "Developer"
},
"database": {
"host": "localhost",
"port": 3306,
"username": "root",
"password": "password123",
"database_name": "myapp_db"
},
"logging": {
"level": "INFO",
"file_path": "logs/app.log",
"max_size": "10MB",
"backup_count": 5
},
"features": {
"auto_save": true,
"theme": "dark",
"language": "zh-CN",
"plugins": ["plugin1", "plugin2"]
}
}
Pythonimport json
import os
from pathlib import Path
def load_config(config_path='config.json'):
"""
加载JSON配置文件
Args:
config_path: 配置文件路径
Returns:
dict: 配置数据字典
"""
try:
# 检查文件是否存在
if not os.path.exists(config_path):
raise FileNotFoundError(f"配置文件 {config_path} 不存在")
# 读取配置文件
with open(config_path, 'r', encoding='utf-8') as file:
config = json.load(file)
print(f"✅ 成功加载配置文件: {config_path}")
return config
except json.JSONDecodeError as e:
print(f"❌ JSON格式错误: {e}")
return None
except Exception as e:
print(f"❌ 读取配置文件失败: {e}")
return None
# 使用示例
config = load_config()
if config:
print(f"应用名称: {config['app_info']['name']}")
print(f"数据库主机: {config['database']['host']}")

Pythonimport json
import os
from pathlib import Path
def save_config(config_data, config_path='config.json'):
"""
保存配置数据到JSON文件
Args:
config_data: 配置数据字典
config_path: 配置文件路径
"""
try:
# 确保目录存在
config_dir = os.path.dirname(config_path)
if config_dir and not os.path.exists(config_dir):
os.makedirs(config_dir)
# 保存配置文件
with open(config_path, 'w', encoding='utf-8') as file:
json.dump(config_data, file,
ensure_ascii=False, # 支持中文
indent=4, # 格式化输出
separators=(',', ': ')) # 分隔符
print(f"✅ 配置文件保存成功: {config_path}")
return True
except Exception as e:
print(f"❌ 保存配置文件失败: {e}")
return False
# 使用示例
new_config = {
"app_info": {
"name": "MyApp",
"version": "2.0.0"
},
"database": {
"host": "127.0.0.1",
"port": 3306
}
}
save_config(new_config, 'config.json')

让我们创建一个完整的配置管理器类,支持动态读写、默认值设置、配置验证等功能:
Pythonimport json
import os
from typing import Any, Dict, Optional
from pathlib import Path
class ConfigManager:
"""
JSON配置文件管理器
支持动态读写、默认配置、配置验证等功能
"""
def __init__(self, config_path: str = 'config.json'):
self.config_path = Path(config_path)
self.config_data = {}
self.default_config = self._get_default_config()
# 初始化配置
self._initialize_config()
def _get_default_config(self) -> Dict[str, Any]:
"""获取默认配置"""
return {
"app_info": {
"name": "DefaultApp",
"version": "1.0.0",
"debug": False
},
"database": {
"host": "localhost",
"port": 3306,
"timeout": 30
},
"logging": {
"level": "INFO",
"file_path": "logs/app.log"
}
}
def _initialize_config(self):
"""初始化配置文件"""
if self.config_path.exists():
self.load()
else:
print("⚠️ 配置文件不存在,使用默认配置")
self.config_data = self.default_config.copy()
self.save()
def load(self) -> bool:
"""加载配置文件"""
try:
with open(self.config_path, 'r', encoding='utf-8') as file:
loaded_config = json.load(file)
# 合并默认配置(确保所有必需的键都存在)
self.config_data = self._merge_config(self.default_config, loaded_config)
print(f"✅ 配置加载成功: {self.config_path}")
return True
except json.JSONDecodeError as e:
print(f"❌ JSON格式错误: {e}")
return False
except Exception as e:
print(f"❌ 加载配置失败: {e}")
return False
def save(self) -> bool:
"""保存配置文件"""
try:
# 确保目录存在
self.config_path.parent.mkdir(parents=True, exist_ok=True)
with open(self.config_path, 'w', encoding='utf-8') as file:
json.dump(self.config_data, file,
ensure_ascii=False,
indent=4,
separators=(',', ': '))
print(f"✅ 配置保存成功: {self.config_path}")
return True
except Exception as e:
print(f"❌ 保存配置失败: {e}")
return False
def get(self, key_path: str, default: Any = None) -> Any:
"""
获取配置值(支持点号路径)
Args:
key_path: 配置键路径,如 'database.host'
default: 默认值
Returns:
配置值
"""
try:
keys = key_path.split('.')
value = self.config_data
for key in keys:
value = value[key]
return value
except (KeyError, TypeError):
return default
def set(self, key_path: str, value: Any, auto_save: bool = True) -> bool:
"""
设置配置值(支持点号路径)
Args:
key_path: 配置键路径
value: 配置值
auto_save: 是否自动保存
Returns:
是否设置成功
"""
try:
keys = key_path.split('.')
data = self.config_data
# 创建嵌套字典结构
for key in keys[:-1]:
if key not in data:
data[key] = {}
data = data[key]
# 设置最终值
data[keys[-1]] = value
if auto_save:
self.save()
return True
except Exception as e:
print(f"❌ 设置配置失败: {e}")
return False
def _merge_config(self, default: Dict, loaded: Dict) -> Dict:
"""合并默认配置和加载的配置"""
result = default.copy()
for key, value in loaded.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = self._merge_config(result[key], value)
else:
result[key] = value
return result
def validate(self) -> bool:
"""验证配置文件完整性"""
required_keys = [
'app_info.name',
'app_info.version',
'database.host',
'database.port'
]
for key in required_keys:
if self.get(key) is None:
print(f"❌ 缺少必需的配置项: {key}")
return False
print("✅ 配置验证通过")
return True
def reset_to_default(self):
"""重置为默认配置"""
self.config_data = self.default_config.copy()
self.save()
print("🔄 已重置为默认配置")
def backup(self, backup_path: Optional[str] = None):
"""备份配置文件"""
if backup_path is None:
backup_path = f"{self.config_path}.backup"
try:
import shutil
shutil.copy2(self.config_path, backup_path)
print(f"📦 配置备份成功: {backup_path}")
return True
except Exception as e:
print(f"❌ 备份失败: {e}")
return False
Python# 创建配置管理器实例
config_manager = ConfigManager('config/app_config.json')
# 验证配置
config_manager.validate()
# 读取配置
app_name = config_manager.get('app_info.name')
db_host = config_manager.get('database.host')
debug_mode = config_manager.get('app_info.debug', False)
print(f"应用名称: {app_name}")
print(f"数据库主机: {db_host}")
print(f"调试模式: {debug_mode}")
# 修改配置
config_manager.set('app_info.debug', True)
config_manager.set('database.timeout', 60)
config_manager.set('new_section.custom_value', 'test')
# 备份配置
config_manager.backup()
# 重置配置(如果需要)
# config_manager.reset_to_default()

对于敏感信息,我们可以添加简单的加密功能:
Pythonimport base64
from cryptography.fernet import Fernet
from appConfigManager import ConfigManager
class SecureConfigManager(ConfigManager):
"""安全配置管理器(支持敏感信息加密)"""
def __init__(self, config_path: str, encryption_key: bytes = None):
self.encryption_key = encryption_key or Fernet.generate_key()
self.cipher = Fernet(self.encryption_key)
super().__init__(config_path)
def encrypt_value(self, value: str) -> str:
"""加密配置值"""
encrypted = self.cipher.encrypt(value.encode())
return base64.b64encode(encrypted).decode()
def decrypt_value(self, encrypted_value: str) -> str:
"""解密配置值"""
encrypted_bytes = base64.b64decode(encrypted_value.encode())
decrypted = self.cipher.decrypt(encrypted_bytes)
return decrypted.decode()
def set_secure(self, key_path: str, value: str, auto_save: bool = True):
"""设置加密配置值"""
encrypted_value = self.encrypt_value(value)
return self.set(f"{key_path}_encrypted", encrypted_value, auto_save)
def get_secure(self, key_path: str, default: str = None) -> str:
"""获取并解密配置值"""
encrypted_value = self.get(f"{key_path}_encrypted")
if encrypted_value:
return self.decrypt_value(encrypted_value)
return default
通过本文的详细讲解,我们掌握了Python读写JSON配置文件的完整技能体系。让我们回顾三个核心要点:
1. 基础操作掌握:使用Python内置json模块实现配置文件的读写,注意编码格式和异常处理,确保在Windows环境下的稳定性。
2. 实战技巧应用:通过ConfigManager类实现高级功能,支持点号路径访问、默认值合并、配置验证等特性,大幅提升开发效率。
3. 最佳实践遵循:采用结构化设计、错误处理、备份机制等最佳实践,构建健壮可维护的配置管理系统。
掌握这些技能后,你的Python开发项目将更加专业和可维护。无论是桌面应用、Web服务还是上位机开发,JSON配置文件都将成为你的得力助手。记住,好的配置管理是优秀应用的基础,投入时间学习这些技巧绝对值得!
现在就动手试试吧,让你的Python应用拥有更优雅的配置管理方案!
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!