123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- import json
- import os
- from pathlib import Path
- from typing import Dict, Any, Optional, Union, List
- import yaml
- # 全局配置字典
- _CONFIG: Dict[str, Any] = {}
- # 默认配置
- DEFAULT_CONFIG = {
- # 数据处理配置
- "processing": {
- "use_parallel": True,
- "max_workers": None, # None表示使用CPU核心数
- "batch_size": 10000,
- "use_vectorized": True
- },
- # 数据库配置
- "database": {
- "batch_query_size": 10000,
- "use_parallel_query": True,
- "max_db_workers": None
- },
- # 插件配置
- "plugins": {
- "enabled": True,
- "auto_discover": True
- },
- # 日志配置
- "logging": {
- "level": "INFO",
- "log_to_file": True,
- "log_dir": "logs"
- },
- # 坐标系配置
- "coordinates": {
- "utm_zone": 51,
- "x_offset": 0.0,
- "y_offset": 0.0
- },
- # 文件路径配置
- "paths": {
- "resources_dir": "resources",
- "plugins_dir": "plugins",
- "output_dir": "output",
- "engine_path": "_internal/engine",
- "map_path": "_internal/data_map",
- "dbc_path": "_internal/VBox.dbc"
- }
- }
- def load_config(config_path: Optional[Union[str, Path]] = None) -> Dict[str, Any]:
- """加载配置文件
-
- Args:
- config_path: 配置文件路径,支持JSON和YAML格式
-
- Returns:
- 配置字典
- """
- global _CONFIG
-
- # 首先使用默认配置
- _CONFIG = DEFAULT_CONFIG.copy()
-
- if config_path is None:
- # 尝试查找默认配置文件
- default_paths = [
- Path("config.json"),
- Path("config.yaml"),
- Path("config.yml"),
- Path("config/config.json"),
- Path("config/config.yaml"),
- Path("config/config.yml")
- ]
-
- for path in default_paths:
- if path.exists():
- config_path = path
- break
-
- if config_path is None:
- print("未找到配置文件,使用默认配置")
- return _CONFIG
-
- # 确保config_path是Path对象
- if isinstance(config_path, str):
- config_path = Path(config_path)
-
- if not config_path.exists():
- print(f"配置文件不存在: {config_path},使用默认配置")
- return _CONFIG
-
- try:
- # 根据文件扩展名选择解析方法
- suffix = config_path.suffix.lower()
-
- if suffix in [".yaml", ".yml"]:
- with open(config_path, "r", encoding="utf-8") as f:
- user_config = yaml.safe_load(f)
- elif suffix == ".json":
- with open(config_path, "r", encoding="utf-8") as f:
- user_config = json.load(f)
- else:
- print(f"不支持的配置文件格式: {suffix},使用默认配置")
- return _CONFIG
-
- # 递归合并配置
- _CONFIG = _merge_configs(_CONFIG, user_config)
- print(f"成功加载配置文件: {config_path}")
-
- except Exception as e:
- print(f"加载配置文件失败: {e}")
-
- return _CONFIG
- def _merge_configs(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
- """递归合并配置字典
-
- Args:
- base: 基础配置
- override: 覆盖配置
-
- Returns:
- 合并后的配置
- """
- result = base.copy()
-
- for key, value in override.items():
- # 如果两个都是字典,递归合并
- if key in result and isinstance(result[key], dict) and isinstance(value, dict):
- result[key] = _merge_configs(result[key], value)
- else:
- # 否则直接覆盖
- result[key] = value
-
- return result
- def get_config(section: Optional[str] = None) -> Any:
- """获取配置
-
- Args:
- section: 配置节名称,如果为None则返回整个配置字典
-
- Returns:
- 配置值或配置字典
- """
- global _CONFIG
-
- # 如果配置为空,加载默认配置
- if not _CONFIG:
- _CONFIG = DEFAULT_CONFIG.copy()
-
- if section is None:
- return _CONFIG
-
- # 支持点号分隔的多级配置访问,如 "database.batch_query_size"
- if "." in section:
- parts = section.split(".")
- current = _CONFIG
- for part in parts:
- if part in current:
- current = current[part]
- else:
- print(f"配置节不存在: {section}")
- return None
- return current
-
- # 单级配置访问
- return _CONFIG.get(section)
- def set_config(section: str, value: Any) -> None:
- """设置配置
-
- Args:
- section: 配置节名称,支持点号分隔的多级配置
- value: 配置值
- """
- global _CONFIG
-
- # 如果配置为空,加载默认配置
- if not _CONFIG:
- _CONFIG = DEFAULT_CONFIG.copy()
-
- # 支持点号分隔的多级配置设置
- if "." in section:
- parts = section.split(".")
- current = _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
- else:
- # 单级配置设置
- _CONFIG[section] = value
- def save_config(config_path: Union[str, Path], format: str = "json") -> bool:
- """保存配置到文件
-
- Args:
- config_path: 配置文件路径
- format: 文件格式,支持 "json" 和 "yaml"
-
- Returns:
- 是否保存成功
- """
- global _CONFIG
-
- # 确保config_path是Path对象
- if isinstance(config_path, str):
- config_path = Path(config_path)
-
- # 确保目录存在
- config_path.parent.mkdir(parents=True, exist_ok=True)
-
- try:
- # 根据格式选择保存方法
- if format.lower() == "yaml":
- with open(config_path, "w", encoding="utf-8") as f:
- yaml.dump(_CONFIG, f, default_flow_style=False, sort_keys=False)
- else: # 默认使用JSON
- with open(config_path, "w", encoding="utf-8") as f:
- json.dump(_CONFIG, f, indent=2, ensure_ascii=False)
-
- print(f"配置已保存到: {config_path}")
- return True
-
- except Exception as e:
- print(f"保存配置失败: {e}")
- return False
- def update_config(new_config: Dict[str, Any]) -> None:
- """更新全局配置
-
- Args:
- new_config: 新的配置字典,将与现有配置合并
- """
- global _CONFIG
- _CONFIG = _merge_configs(_CONFIG, new_config)
- print("配置已更新")
- # 初始化时加载配置
- load_config()
|