1. 基本读写操作
读取 json 配置文件
import json
# 创建示例配置文件
config_data = {
"database": {
"host": "localhost",
"port": 3306,
"username": "admin"
},
"settings": {
"debug": true,
"log_level": "info"
}
}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(config_data, f, indent=2, ensure_ascii=false)
# 读取 json 文件
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print("配置文件内容:")
print(json.dumps(config, indent=2, ensure_ascii=false))
# 访问配置值
db_host = config["database"]["host"]
debug_mode = config["settings"]["debug"]
print(f"\n数据库主机: {db_host}")
print(f"调试模式: {debug_mode}")
写入 json 配置文件
import json
# 创建配置数据
config = {
"app": {
"name": "我的应用",
"version": "1.0.0"
},
"server": {
"host": "0.0.0.0",
"port": 8080
}
}
# 写入到文件
with open("app_config.json", "w", encoding="utf-8") as f:
json.dump(config, f, indent=4, ensure_ascii=false)
print("配置文件已保存到: app_config.json")
# 验证写入
with open("app_config.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(f"应用名称: {loaded['app']['name']}")
print(f"服务器端口: {loaded['server']['port']}")
2. 简单配置管理器
import json
import os
from typing import any, dict
class simpleconfig:
def __init__(self, filename: str = "config.json"):
self.filename = filename
self.config = {}
def load(self) -> dict[str, any]:
"""加载配置文件"""
if os.path.exists(self.filename):
with open(self.filename, "r", encoding="utf-8") as f:
self.config = json.load(f)
else:
self.config = self.get_default_config()
self.save()
return self.config
def save(self) -> none:
"""保存配置文件"""
with open(self.filename, "w", encoding="utf-8") as f:
json.dump(self.config, f, indent=2, ensure_ascii=false)
def get_default_config(self) -> dict[str, any]:
"""获取默认配置"""
return {
"app": {
"name": "默认应用",
"version": "1.0.0"
},
"database": {
"host": "localhost",
"port": 5432
}
}
def get(self, *keys) -> any:
"""获取配置值"""
value = self.config
for key in keys:
if isinstance(value, dict) and key in value:
value = value[key]
else:
return none
return value
def set(self, *keys_and_value) -> none:
"""设置配置值
参数格式: key1, key2, ..., value
例如: set("database", "host", "192.168.1.100")
"""
if len(keys_and_value) < 2:
raise valueerror("至少需要2个参数: keys和value")
*keys, value = keys_and_value
# 遍历到倒数第二个键
current = self.config
for key in keys[:-1]:
if key not in current or not isinstance(current[key], dict):
current[key] = {}
current = current[key]
# 设置最后一个键的值
current[keys[-1]] = value
self.save()
# 使用示例
config = simpleconfig("my_config.json")
# 加载配置
config.load()
# 获取配置
app_name = config.get("app", "name")
print(f"应用名称: {app_name}")
# 设置新配置
config.set("database", "host", "192.168.1.100")
config.set("app", "debug", true)
config.set("logging", "level", "debug")
# 验证设置
print(f"数据库主机: {config.get('database', 'host')}")
print(f"调试模式: {config.get('app', 'debug')}")
print(f"日志级别: {config.get('logging', 'level')}")
# 查看完整的配置
print(f"\n完整配置: {json.dumps(config.config, indent=2, ensure_ascii=false)}")
# 清理临时文件
if os.path.exists("my_config.json"):
os.remove("my_config.json")
3. 带环境变量支持的配置
import json
import os
from typing import any, dict
class envconfig:
def __init__(self, config_file: str = "config.json", env_prefix: str = "app_"):
self.config_file = config_file
self.env_prefix = env_prefix
self.config = {}
def load(self) -> dict[str, any]:
"""加载配置,环境变量优先于文件配置"""
# 1. 加载文件配置
if os.path.exists(self.config_file):
with open(self.config_file, "r", encoding="utf-8") as f:
self.config = json.load(f)
else:
self.config = {}
# 2. 用环境变量覆盖
self._apply_env_vars()
return self.config
def _apply_env_vars(self) -> none:
"""应用环境变量到配置"""
for env_key, env_value in os.environ.items():
if env_key.startswith(self.env_prefix):
# 转换环境变量名: app_database_host -> database.host
config_key = env_key[len(self.env_prefix):].lower()
# 转换值类型
value = self._convert_value(env_value)
# 设置到配置中
self._set_nested(config_key, value)
def _convert_value(self, value: str) -> any:
"""转换字符串值为适当类型"""
# 布尔值
if value.lower() in ("true", "false"):
return value.lower() == "true"
# 数字
try:
if "." in value:
return float(value)
return int(value)
except valueerror:
pass
# 列表(逗号分隔)
if "," in value:
return [item.strip() for item in value.split(",")]
return value
def _set_nested(self, key_path: str, value: any) -> none:
"""设置嵌套配置"""
parts = key_path.split("_")
current = self.config
for part in parts[:-1]:
if part not in current or not isinstance(current[part], dict):
current[part] = {}
current = current[part]
current[parts[-1]] = value
def save(self) -> none:
"""保存配置到文件"""
with open(self.config_file, "w", encoding="utf-8") as f:
json.dump(self.config, f, indent=2, ensure_ascii=false)
# 使用示例
# 设置环境变量
os.environ["app_database_host"] = "prod-db.example.com"
os.environ["app_debug"] = "true"
os.environ["app_log_level"] = "warning"
# 创建文件配置
file_config = {
"database": {
"host": "localhost", # 将被环境变量覆盖
"port": 3306
},
"app": {
"debug": false, # 将被环境变量覆盖
"log_level": "info" # 将被环境变量覆盖
}
}
# 保存文件配置
with open("env_config.json", "w", encoding="utf-8") as f:
json.dump(file_config, f, indent=2, ensure_ascii=false)
# 加载配置
config = envconfig("env_config.json")
config_data = config.load()
print("最终配置:")
print(json.dumps(config_data, indent=2, ensure_ascii=false))
# 清理
os.remove("env_config.json")
del os.environ["app_database_host"]
del os.environ["app_debug"]
del os.environ["app_log_level"]
4. 处理特殊数据类型的配置
import json
from datetime import datetime, date
from decimal import decimal
from enum import enum
from typing import any
class customjsonencoder(json.jsonencoder):
"""自定义 json 编码器,支持更多数据类型"""
def default(self, obj: any) -> any:
if isinstance(obj, (datetime, date)):
return obj.isoformat()
elif isinstance(obj, decimal):
return float(obj)
elif isinstance(obj, enum):
return obj.value
elif hasattr(obj, '__dict__'):
return obj.__dict__
return super().default(obj)
# 定义数据类型
class loglevel(enum):
debug = "debug"
info = "info"
warning = "warning"
error = "error"
# 创建包含特殊类型的数据
config_data = {
"app": {
"name": "数据分析",
"created": datetime.now(),
"version": "2.0.0"
},
"database": {
"host": "localhost",
"port": 5432,
"timeout": 30.5
},
"logging": {
"level": loglevel.info,
"retention_days": decimal("90.5")
},
"features": ["auth", "api", "dashboard"]
}
# 使用自定义编码器保存
with open("special_config.json", "w", encoding="utf-8") as f:
json.dump(config_data, f, cls=customjsonencoder, indent=2, ensure_ascii=false)
print("包含特殊类型的配置文件已保存")
# 读取和验证
with open("special_config.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print("\n读取的配置:")
print(f"应用名称: {loaded['app']['name']}")
print(f"创建时间: {loaded['app']['created']}")
print(f"日志级别: {loaded['logging']['level']}")
print(f"保留天数: {loaded['logging']['retention_days']}")
# 清理
import os
os.remove("special_config.json")
5. 配置验证
import json
from typing import any, dict, list
class configvalidator:
"""简单的配置验证器"""
def validate(self, config: dict[str, any], rules: dict[str, any]) -> list[str]:
"""验证配置"""
errors = []
for key, rule in rules.items():
if key not in config:
if rule.get("required", false):
errors.append(f"缺少必要字段: {key}")
continue
value = config[key]
value_type = rule.get("type")
# 检查类型
if value_type and not isinstance(value, value_type):
errors.append(f"{key} 应为 {value_type.__name__} 类型")
# 检查枚举值
if "enum" in rule and value not in rule["enum"]:
errors.append(f"{key} 的值 {value} 不在允许范围内: {rule['enum']}")
# 检查范围
if "min" in rule and value < rule["min"]:
errors.append(f"{key} 的值 {value} 小于最小值 {rule['min']}")
if "max" in rule and value > rule["max"]:
errors.append(f"{key} 的值 {value} 大于最大值 {rule['max']}")
return errors
# 使用示例
config = {
"app": {
"name": "我的应用",
"version": "1.0.0"
},
"database": {
"host": "localhost",
"port": 3306,
"timeout": 30
},
"server": {
"port": 8080,
"workers": 4
}
}
# 定义验证规则
validation_rules = {
"app": {
"type": dict,
"required": true
},
"database": {
"type": dict,
"required": true
},
"server": {
"type": dict,
"required": true
}
}
database_rules = {
"host": {
"type": str,
"required": true
},
"port": {
"type": int,
"required": true,
"min": 1,
"max": 65535
},
"timeout": {
"type": int,
"required": true,
"min": 1
}
}
# 验证配置
validator = configvalidator()
# 验证顶层
errors = validator.validate(config, validation_rules)
if errors:
print("配置验证失败:")
for error in errors:
print(f" - {error}")
else:
print("✓ 顶层配置验证通过")
# 验证数据库配置
db_errors = validator.validate(config["database"], database_rules)
if db_errors:
print("数据库配置验证失败:")
for error in db_errors:
print(f" - {error}")
else:
print("✓ 数据库配置验证通过")
# 保存验证通过的配置
if not errors and not db_errors:
with open("validated_config.json", "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=false)
print("\n✓ 配置已保存到: validated_config.json")
# 清理
import os
os.remove("validated_config.json")
快速使用总结
- 基本读写:使用
json.load()和json.dump() - 中文支持:添加
ensure_ascii=false - 格式美观:使用
indent参数 - 错误处理:检查文件是否存在
- 类型转换:json 支持基本类型,复杂类型需要自定义处理
到此这篇关于python读写json配置文件的简明学习指南的文章就介绍到这了,更多相关python读写json配置文件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论