From fa737711d44a2ce5c7eaed8352cceea441e86c51 Mon Sep 17 00:00:00 2001 From: KenanZhu <3471685733@qq.com> Date: Fri, 16 Jan 2026 23:23:03 +0800 Subject: [PATCH] =?UTF-8?q?optimize(ConfigReader,=20ConfigWriter):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E7=B1=BB=E9=80=BB=E8=BE=91=EF=BC=8C=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/ConfigReader.py | 62 +++++++++++++++++++++++++++------------ src/utils/ConfigWriter.py | 51 +++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/src/utils/ConfigReader.py b/src/utils/ConfigReader.py index 53cd52c..e9c0805 100644 --- a/src/utils/ConfigReader.py +++ b/src/utils/ConfigReader.py @@ -8,63 +8,89 @@ You may use, modify, and distribute this file under the terms of the MIT License See the LICENSE file for details. """ import json +import copy + +from typing import Any class ConfigReader: + """ + Config reader class. + + This class is used to read config file in JSON format. + + Args: + config_path (str): The path of config file. + + Examples: + >>> print(open("config.json", "r", encoding="utf-8").read()) + { + "key1": { + "key2": "value1" + } + } + >>> config_reader = ConfigReader("config.json") + >>> config_reader.get("key1/key2") + "value1" + """ def __init__( self, config_path: str ): - self._config_path = config_path - self._config_data = {} - if not self.__readConfig(): - return None + self.__config_path = config_path + self.__config_data = None + self.__readConfig() def __readConfig( self - ) -> bool: + ): try: - with open(self._config_path, 'r', encoding='utf-8') as file: - self._config_data = json.load(file) - return True + with open(self.__config_path, 'r', encoding='utf-8') as file: + self.__config_data = json.load(file) + except FileNotFoundError as e: + raise Exception(f"Config file not found: {self.__config_path}") from e + except PermissionError as e: + raise Exception(f"Without enough permission to read config file: {self.__config_path}") from e + except json.JSONDecodeError as e: + raise Exception(f"JSON decode error in config file: {self.__config_path}") from e except Exception as e: - print(f"Error reading config file: {e}") - return False + raise Exception(f"Unknown error occurred while reading config file: {e}") from e def getConfigs( self ) -> dict: - return self._config_data.copy() + return self.__config_data.copy() def getConfig( self, key: str - ) -> dict: + ) -> Any: - return self._config_data.get(key, {}) + config = self.__config_data.get(key, {}) + return copy.deepcopy(config) def get( self, key: str, - default: any = None - ) -> any: + default: Any = None + ) -> Any: keys = key.split('/') - current = self._config_data + current = self.__config_data for k in keys: if isinstance(current, dict) and k in current: current = current[k] else: return default - return current + return copy.deepcopy(current) def hasConfig( @@ -86,4 +112,4 @@ class ConfigReader: self ) -> str: - return self._config_path + return self.__config_path diff --git a/src/utils/ConfigWriter.py b/src/utils/ConfigWriter.py index b935d2c..5373c56 100644 --- a/src/utils/ConfigWriter.py +++ b/src/utils/ConfigWriter.py @@ -9,8 +9,35 @@ See the LICENSE file for details. """ import json +from typing import Any + class ConfigWriter: + """ + Config writer class. + + This class is used to write config file in JSON format. + + Args: + config_path (str): The path of config file. + config_data (dict): The config data to be written. + + Examples: + >>> config_data = { + ... "key1": { + ... "key2": "value1" + ... } + ... } + >>> config_writer = ConfigWriter("config.json", config_data) + >>> config_writer.set("key1/key2", "value1") + True + >>> print(open("config.json", "r", encoding="utf-8").read()) + { + "key1": { + "key2": "value1" + } + } + """ def __init__( self, @@ -19,23 +46,25 @@ class ConfigWriter: ): self.__config_path = config_path - self.__config_data = config_data if config_data is not None else {} - if config_data is None: - return None - if not self.__writeConfig(): - return None + self.__config_data = config_data.copy() if config_data is not None else {} + self.__writeConfig() def __writeConfig( self - ) -> bool: + ): try: - with open(self.__config_path, "w") as f: + with open(self.__config_path, "w", encoding="utf-8") as f: json.dump(self.__config_data, f, indent=4, sort_keys=False) - return True - except: - return False + except PermissionError as e: + raise Exception(f"Without enough permission to write config file: {self.__config_path}") from e + except IOError as e: + raise Exception(f"IO error occurred while writing config file: {self.__config_path}") from e + except TypeError as e: + raise Exception(f"Config data contains invalid type that can not be JSON serialized: {e}") from e + except Exception as e: + raise Exception(f"Unknown error occurred while writing config file: {e}") from e def setConfigs( @@ -60,7 +89,7 @@ class ConfigWriter: def set( self, key: str, - value: dict + value: Any ) -> bool: keys = key.replace("\\", "/").split("/")