This commit is contained in:
2025-10-31 14:30:42 +08:00
parent 93d412b8fe
commit bd0815d0e7
23 changed files with 2394 additions and 28 deletions

278
common/ini_handler.py Normal file
View File

@ -0,0 +1,278 @@
import os
import configparser
from typing import Dict, Any, Optional, List
class IniHandlerError(Exception):
"""INI处理器异常基类"""
def __init__(self, message: str, file_path: str = None):
self.file_path = file_path
if file_path:
message = f"{message} (文件: {file_path})"
super().__init__(message)
class IniHandler:
"""
INI文件操作处理器基于文件路径的缓存
"""
_instances = {} # 按文件路径缓存的实例
def __new__(cls, file_path: str):
if file_path not in cls._instances:
instance = super().__new__(cls)
instance._file_path = file_path
instance._config = None # 单个文件的配置对象
cls._instances[file_path] = instance
return cls._instances[file_path]
def __init__(self, file_path: str):
"""
初始化INI处理器
Args:
file_path: INI文件路径
"""
# 文件路径已经在__new__中设置这里不需要重复设置
pass
def load_config(self) -> configparser.ConfigParser:
"""
加载并缓存INI配置文件
"""
if self._config is not None:
return self._config
if not os.path.exists(self._file_path):
raise IniHandlerError("INI文件不存在", self._file_path)
try:
config = configparser.ConfigParser()
config.read(self._file_path, encoding='utf-8')
self._config = config
return config
except Exception as e:
raise IniHandlerError(f"读取INI文件失败: {e}", self._file_path)
def get_value(self, section: str, option: str) -> Any:
"""
获取INI文件中的值
Args:
section: 节名
option: 选项名
default: 默认值
Returns:
获取的值,如果不存在则返回默认值
"""
try:
config = self.load_config()
if config.has_section(section) and config.has_option(section, option):
return config.get(section, option)
except IniHandlerError:
# 文件不存在或读取失败时返回默认值
return default
except Exception as e:
raise IniHandlerError(f"获取INI值失败: {e}", self._file_path)
def get_int_value(self, section: str, option: str) -> int:
"""
获取INI文件中的整数值
Args:
section: 节名
option: 选项名
default: 默认值
Returns:
获取的整数值,如果不存在或转换失败则返回默认值
"""
try:
config = self.load_config()
if config.has_section(section) and config.has_option(section, option):
return config.getint(section, option)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"获取INI整数值失败: {e}", self._file_path)
def get_float_value(self, section: str, option: str) -> float:
"""
获取INI文件中的浮点数值
Args:
section: 节名
option: 选项名
default: 默认值
Returns:
获取的浮点数值,如果不存在或转换失败则返回默认值
"""
try:
config = self.load_config()
if config.has_section(section) and config.has_option(section, option):
return config.getfloat(section, option)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"获取INI浮点数值失败: {e}", self._file_path)
def get_boolean_value(self, section: str, option: str) -> bool:
"""
获取INI文件中的布尔值
Args:
section: 节名
option: 选项名
default: 默认值
Returns:
获取的布尔值,如果不存在或转换失败则返回默认值
"""
try:
config = self.load_config()
if config.has_section(section) and config.has_option(section, option):
return config.getboolean(section, option)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"获取INI布尔值失败: {e}", self._file_path)
def get_section(self, section: str) -> Dict[str, str]:
"""
获取INI文件中的整个节
Args:
section: 节名
Returns:
节中所有键值对的字典,如果节不存在则返回空字典
"""
try:
config = self.load_config()
if config.has_section(section):
return dict(config[section])
return {}
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"获取INI节失败: {e}", self._file_path)
def get_sections(self) -> List[str]:
"""
获取INI文件中的所有节名
Returns:
节名列表
"""
try:
config = self.load_config()
return config.sections()
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"获取INI节名列表失败: {e}", self._file_path)
def remove_section(self, section: str) -> None:
"""
移除INI文件中的节
Args:
section: 节名
"""
try:
config = self.load_config()
if config.has_section(section):
config.remove_section(section)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"移除INI节失败: {e}", self._file_path)
def remove_option(self, section: str, option: str) -> None:
"""
移除INI文件中的选项
Args:
section: 节名
option: 选项名
"""
try:
config = self.load_config()
if config.has_section(section) and config.has_option(section, option):
config.remove_option(section, option)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"移除INI选项失败: {e}", self._file_path)
def has_section(self, section: str) -> bool:
"""
检查INI文件中是否存在指定的节
Args:
section: 节名
Returns:
bool: 是否存在
"""
try:
config = self.load_config()
return config.has_section(section)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"检查INI节失败: {e}", self._file_path)
def has_option(self, section: str, option: str) -> bool:
"""
检查INI文件中是否存在指定的选项
Args:
section: 节名
option: 选项名
Returns:
bool: 是否存在
"""
try:
config = self.load_config()
return config.has_option(section, option)
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"检查INI选项失败: {e}", self._file_path)
def write_ini_file(self) -> bool:
"""
写入INI文件持久化,写入前先set_value,set_value设置1或多个值后调用此方法
Returns:
bool: 是否写入成功
"""
try:
# 确保目录存在
dir_path = os.path.dirname(self._file_path)
if dir_path and not os.path.exists(dir_path):
os.makedirs(dir_path)
# 写入文件
with open(self._file_path, 'w', encoding='utf-8') as f:
self._config.write(f)
return True
except Exception as e:
raise IniHandlerError(f"写入INI文件失败: {e}", self._file_path)
def set_value(self, section: str, option: str, value: Any) -> None:
"""
设置INI文件中的值
Args:
section: 节名
option: 选项名
value: 要设置的值
"""
try:
config = self.load_config()
if not config.has_section(section):
config.add_section(section)
config.set(section, option, str(value))
except IniHandlerError:
raise
except Exception as e:
raise IniHandlerError(f"设置INI值失败: {e}", self._file_path)