本文目录导读:

我来介绍几种合并配置文件的方法,从简单到进阶:
简单拼接(适用于相同格式的配置文件)
def merge_config_files_simple(file_list, output_file):
"""简单拼接多个配置文件"""
with open(output_file, 'w', encoding='utf-8') as outfile:
for fname in file_list:
with open(fname, 'r', encoding='utf-8') as infile:
outfile.write(infile.read())
outfile.write('\n') # 添加换行符
# 使用示例
files = ['config1.ini', 'config2.ini', 'config3.ini']
merge_config_files_simple(files, 'merged_config.ini')
合并JSON配置文件
import json
import glob
def merge_json_configs(config_files):
"""合并多个JSON配置文件"""
merged_config = {}
for file_path in config_files:
try:
with open(file_path, 'r', encoding='utf-8') as f:
config = json.load(f)
# 递归合并配置
merged_config = deep_merge(merged_config, config)
except FileNotFoundError:
print(f"文件不存在: {file_path}")
except json.JSONDecodeError:
print(f"JSON格式错误: {file_path}")
return merged_config
def deep_merge(base, override):
"""深度合并字典"""
merged = base.copy()
for key, value in override.items():
if key in merged and isinstance(merged[key], dict) and isinstance(value, dict):
merged[key] = deep_merge(merged[key], value)
else:
merged[key] = value
return merged
# 使用示例
config_files = glob.glob('configs/*.json')
merged = merge_json_configs(config_files)
with open('merged_config.json', 'w', encoding='utf-8') as f:
json.dump(merged, f, indent=4, ensure_ascii=False)
合并INI配置文件
import configparser
from pathlib import Path
def merge_ini_configs(config_files, output_file):
"""合并INI配置文件"""
merged_config = configparser.ConfigParser()
for file_path in config_files:
try:
config = configparser.ConfigParser()
config.read(file_path, encoding='utf-8')
for section in config.sections():
if not merged_config.has_section(section):
merged_config.add_section(section)
for key, value in config.items(section):
merged_config.set(section, key, value)
except configparser.Error as e:
print(f"INI文件错误 {file_path}: {e}")
with open(output_file, 'w', encoding='utf-8') as f:
merged_config.write(f)
# 使用示例
ini_files = ['app.ini', 'database.ini', 'cache.ini']
merge_ini_configs(ini_files, 'merged_config.ini')
合并YAML配置文件
import yaml
import os
def merge_yaml_configs(config_files):
"""合并YAML配置文件"""
merged_config = {}
for file_path in config_files:
try:
with open(file_path, 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
if config:
merged_config = deep_merge(merged_config, config)
except FileNotFoundError:
print(f"文件不存在: {file_path}")
except yaml.YAMLError as e:
print(f"YAML格式错误 {file_path}: {e}")
return merged_config
# 使用示例
yaml_files = ['config_default.yaml', 'config_custom.yaml']
merged = merge_yaml_configs(yaml_files)
with open('merged_config.yaml', 'w', encoding='utf-8') as f:
yaml.dump(merged, f, default_flow_style=False, allow_unicode=True)
智能合并(支持优先级)
import json
from pathlib import Path
from typing import Dict, List
class ConfigMerger:
"""智能配置文件合并器"""
def __init__(self, config_dir: str = '.'):
self.config_dir = Path(config_dir)
def merge_with_priority(self, base_file: str, override_files: List[str], output_file: str):
"""
按优先级合并配置文件
后面的文件覆盖前面的文件
"""
all_files = [base_file] + override_files
merged_config = {}
for file_path in all_files:
full_path = self.config_dir / file_path
config = self._load_config(full_path)
if config:
# 记录来源
self._add_source_info(config, str(file_path))
merged_config = deep_merge(merged_config, config)
# 保存合并结果
output_path = self.config_dir / output_file
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(merged_config, f, indent=4, ensure_ascii=False)
return merged_config
def _load_config(self, file_path: Path) -> Dict:
"""根据文件扩展名加载配置"""
if not file_path.exists():
print(f"文件不存在: {file_path}")
return {}
suffix = file_path.suffix.lower()
if suffix == '.json':
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
elif suffix == '.yaml' or suffix == '.yml':
import yaml
with open(file_path, 'r', encoding='utf-8') as f:
return yaml.safe_load(f)
elif suffix == '.ini':
import configparser
config = configparser.ConfigParser()
config.read(str(file_path), encoding='utf-8')
return {section: dict(config.items(section))
for section in config.sections()}
else:
print(f"不支持的格式: {suffix}")
return {}
def _add_source_info(self, config: Dict, source: str):
"""添加配置来源信息"""
if isinstance(config, dict):
config['_source'] = source
for value in config.values():
if isinstance(value, dict):
self._add_source_info(value, source)
# 使用示例
merger = ConfigMerger('./configs')
# 基础配置 + 环境配置 + 本地覆盖
merged = merger.merge_with_priority(
base_file='default.json',
override_files=['development.json', 'local.json'],
output_file='merged_config.json'
)
命令行工具版本
#!/usr/bin/env python3
import argparse
import json
import glob
import os
def main():
"""命令行配置文件合并工具"""
parser = argparse.ArgumentParser(description='合并多个配置文件')
parser.add_argument('files', nargs='+', help='配置文件的路径')
parser.add_argument('-o', '--output', default='merged_config.json',
help='输出文件路径')
parser.add_argument('-t', '--type', choices=['json', 'yaml', 'ini'],
default='json', help='配置文件类型')
parser.add_argument('--overwrite', action='store_true',
help='覆盖已有值(默认保留第一个出现的值)')
args = parser.parse_args()
# 展开通配符
config_files = []
for pattern in args.files:
config_files.extend(glob.glob(pattern))
if not config_files:
print("没有找到配置文件")
return
# 根据类型选择合并方法
if args.type == 'json':
merged = merge_json_configs(config_files)
with open(args.output, 'w', encoding='utf-8') as f:
json.dump(merged, f, indent=4, ensure_ascii=False)
elif args.type == 'yaml':
import yaml
merged = merge_yaml_configs(config_files)
with open(args.output, 'w', encoding='utf-8') as f:
yaml.dump(merged, f, default_flow_style=False)
elif args.type == 'ini':
merge_ini_configs(config_files, args.output)
print(f"已合并 {len(config_files)} 个配置文件到 {args.output}")
if __name__ == '__main__':
main()
使用建议
- 简单场景:使用拼接方式即可
- 结构化数据:推荐使用JSON或YAML格式的深度合并
- 生产环境:建议实现完整的合并器,支持优先级、错误处理和日志
- 配置文件格式:优先使用JSON(标准库支持)或YAML(可读性更好)
- 版本控制:合并前建议备份原始配置
需要根据具体场景选择合适的合并策略!