詳解Python中通用工具類與異常處理
在Python開發(fā)中,編寫可重用的工具類和通用的異常處理機(jī)制是提高代碼質(zhì)量和開發(fā)效率的關(guān)鍵。本文將介紹如何將特定的異常類GlueValidaionException改寫為更通用的ValidationException,并創(chuàng)建一個通用的工具類Utils,包含常用的文件操作和數(shù)據(jù)處理方法。最后,我們將通過代碼示例展示如何使用這些工具。
1. 通用異常類:ValidationException
首先,我們將GlueValidaionException改寫為更通用的ValidationException,使其適用于各種驗證場景。
class ValidationException(Exception): """ 通用驗證異常類,適用于各種驗證場景。 """ def __init__(self, err_message, excep_obj): message = ("[Invalid input detected]\n" f"Exception: {err_message}\n" f"Exception logs: {excep_obj}") super().__init__(message)
2. 通用工具類:Utils
接下來,我們創(chuàng)建一個通用的工具類Utils,包含常用的文件操作和數(shù)據(jù)處理方法。
import json from os.path import join from typing import Dict, List import yaml class Utils: @staticmethod def yaml_to_dict(file_path: str) -> Dict: """ 將YAML文件轉(zhuǎn)換為字典。 :param file_path: YAML文件路徑 :return: 解析后的字典 """ with open(file_path) as yaml_file: yaml_string = yaml_file.read() try: parsed_dict = yaml.safe_load(yaml_string) except yaml.scanner.ScannerError as e: raise ValidationException(f"YAML文件語法錯誤: {file_path}", e) return parsed_dict @staticmethod def yaml_to_class(yaml_file_path: str, cls: type, default_yaml_file_path: str = None): """ 將YAML文件轉(zhuǎn)換為類對象。 :param yaml_file_path: YAML文件路徑 :param cls: 目標(biāo)類 :param default_yaml_file_path: 默認(rèn)YAML文件路徑 :return: 類對象 """ if not yaml_file_path: yaml_file_path = default_yaml_file_path custom_args = Utils.yaml_to_dict(yaml_file_path) if default_yaml_file_path: default_args = Utils.yaml_to_dict(default_yaml_file_path) missing_args = set(default_args) - set(custom_args) for key in list(missing_args): custom_args[key] = default_args[key] try: yaml_as_class = cls(**custom_args) except TypeError as e: raise ValidationException(f"YAML文件轉(zhuǎn)換為類失敗: {yaml_file_path}", e) return yaml_as_class @staticmethod def read_jsonl(file_path: str) -> List: """ 讀取JSONL文件并返回所有JSON對象列表。 :param file_path: JSONL文件路徑 :return: JSON對象列表 """ jsonl_list = [] with open(file_path, "r") as fileobj: while True: single_row = fileobj.readline() if not single_row: break json_object = json.loads(single_row.strip()) jsonl_list.append(json_object) return jsonl_list @staticmethod def read_jsonl_row(file_path: str): """ 逐行讀取JSONL文件并返回JSON對象。 :param file_path: JSONL文件路徑 :return: JSON對象生成器 """ with open(file_path, "r") as fileobj: while True: try: single_row = fileobj.readline() if not single_row: break json_object = json.loads(single_row.strip()) yield json_object except json.JSONDecodeError as e: print(f"JSONL文件讀取錯誤: {file_path}. 錯誤: {e}") continue @staticmethod def append_as_jsonl(file_path: str, args_to_log: Dict): """ 將字典追加到JSONL文件中。 :param file_path: JSONL文件路徑 :param args_to_log: 要追加的字典 """ json_str = json.dumps(args_to_log, default=str) with open(file_path, "a") as fileobj: fileobj.write(json_str + "\n") @staticmethod def save_jsonlist(file_path: str, json_list: List, mode: str = "a"): """ 將JSON對象列表保存到JSONL文件中。 :param file_path: JSONL文件路徑 :param json_list: JSON對象列表 :param mode: 文件寫入模式 """ with open(file_path, mode) as file_obj: for json_obj in json_list: json_str = json.dumps(json_obj, default=str) file_obj.write(json_str + "\n") @staticmethod def str_list_to_dir_path(str_list: List[str]) -> str: """ 將字符串列表拼接為目錄路徑。 :param str_list: 字符串列表 :return: 拼接后的目錄路徑 """ if not str_list: return "" path = "" for dir_name in str_list: path = join(path, dir_name) return path
3. 示例文件內(nèi)容
以下是示例文件的內(nèi)容,包括default_config.yaml、config.yaml和data.jsonl。
default_config.yaml
name: "default_name" value: 100 description: "This is a default configuration."
config.yaml
name: "custom_name" value: 200
data.jsonl
{"id": 1, "name": "Alice", "age": 25} {"id": 2, "name": "Bob", "age": 30} {"id": 3, "name": "Charlie", "age": 35}
4. 代碼示例
以下是如何使用Utils工具類的示例:
# 示例類 class Config: def __init__(self, name, value, description=None): self.name = name self.value = value self.description = description # 示例1: 將YAML文件轉(zhuǎn)換為字典 yaml_dict = Utils.yaml_to_dict("config.yaml") print("YAML文件轉(zhuǎn)換為字典:", yaml_dict) # 示例2: 將YAML文件轉(zhuǎn)換為類對象 config_obj = Utils.yaml_to_class("config.yaml", Config, "default_config.yaml") print("YAML文件轉(zhuǎn)換為類對象:", config_obj.name, config_obj.value, config_obj.description) # 示例3: 讀取JSONL文件 jsonl_list = Utils.read_jsonl("data.jsonl") print("讀取JSONL文件:", jsonl_list) # 示例4: 逐行讀取JSONL文件 print("逐行讀取JSONL文件:") for json_obj in Utils.read_jsonl_row("data.jsonl"): print(json_obj) # 示例5: 將字典追加到JSONL文件 Utils.append_as_jsonl("data.jsonl", {"id": 4, "name": "David", "age": 40}) print("追加數(shù)據(jù)到JSONL文件完成") # 示例6: 將JSON對象列表保存到JSONL文件 Utils.save_jsonlist("data.jsonl", [{"id": 5, "name": "Eve", "age": 45}]) print("保存JSON列表到JSONL文件完成") # 示例7: 將字符串列表拼接為目錄路徑 path = Utils.str_list_to_dir_path(["dir1", "dir2", "dir3"]) print("拼接目錄路徑:", path)
5. 運(yùn)行結(jié)果
運(yùn)行上述代碼后,輸出結(jié)果如下:
YAML文件轉(zhuǎn)換為字典: {'name': 'custom_name', 'value': 200}
YAML文件轉(zhuǎn)換為類對象: custom_name 200 This is a default configuration.
讀取JSONL文件: [{'id': 1, 'name': 'Alice', 'age': 25}, {'id': 2, 'name': 'Bob', 'age': 30}, {'id': 3, 'name': 'Charlie', 'age': 35}]
逐行讀取JSONL文件:
{'id': 1, 'name': 'Alice', 'age': 25}
{'id': 2, 'name': 'Bob', 'age': 30}
{'id': 3, 'name': 'Charlie', 'age': 35}
追加數(shù)據(jù)到JSONL文件完成
保存JSON列表到JSONL文件完成
拼接目錄路徑: dir1/dir2/dir3
6. 完整代碼
import json from os.path import join from typing import Dict, List import yaml from yaml.scanner import ScannerError class ValidationException(Exception): """ 通用驗證異常類,適用于各種驗證場景。 """ def __init__(self, err_message, excep_obj): message = ("[Invalid input detected]\n" f"Exception: {err_message}\n" f"Exception logs: {excep_obj}") super().__init__(message) class Utils: @staticmethod def yaml_to_dict(file_path: str) -> Dict: """ 將YAML文件轉(zhuǎn)換為字典。 :param file_path: YAML文件路徑 :return: 解析后的字典 """ with open(file_path) as yaml_file: yaml_string = yaml_file.read() try: parsed_dict = yaml.safe_load(yaml_string) except ScannerError as e: raise ValidationException(f"YAML文件語法錯誤: {file_path}", e) return parsed_dict @staticmethod def yaml_to_class(yaml_file_path: str, cls: type, default_yaml_file_path: str = None): """ 將YAML文件轉(zhuǎn)換為類對象。 :param yaml_file_path: YAML文件路徑 :param cls: 目標(biāo)類 :param default_yaml_file_path: 默認(rèn)YAML文件路徑 :return: 類對象 """ if not yaml_file_path: yaml_file_path = default_yaml_file_path custom_args = Utils.yaml_to_dict(yaml_file_path) if default_yaml_file_path: default_args = Utils.yaml_to_dict(default_yaml_file_path) missing_args = set(default_args) - set(custom_args) for key in list(missing_args): custom_args[key] = default_args[key] try: yaml_as_class = cls(**custom_args) except TypeError as e: raise ValidationException(f"YAML文件轉(zhuǎn)換為類失敗: {yaml_file_path}", e) return yaml_as_class @staticmethod def read_jsonl(file_path: str) -> List: """ 讀取JSONL文件并返回所有JSON對象列表。 :param file_path: JSONL文件路徑 :return: JSON對象列表 """ jsonl_list = [] with open(file_path, "r") as file_obj: while True: single_row = file_obj.readline() if not single_row: break json_obj = json.loads(single_row.strip()) jsonl_list.append(json_obj) return jsonl_list @staticmethod def read_jsonl_row(file_path: str): """ 逐行讀取JSONL文件并返回JSON對象。 :param file_path: JSONL文件路徑 :return: JSON對象生成器 """ with open(file_path, "r") as file_object: while True: try: single_row = file_object.readline() if not single_row: break json_obj = json.loads(single_row.strip()) yield json_obj except json.JSONDecodeError as e: print(f"JSONL文件讀取錯誤: {file_path}. 錯誤: {e}") continue @staticmethod def append_as_jsonl(file_path: str, args_to_log: Dict): """ 將字典追加到JSONL文件中。 :param file_path: JSONL文件路徑 :param args_to_log: 要追加的字典 """ json_str = json.dumps(args_to_log, default=str) with open(file_path, "a") as file_object: file_object.write(json_str + "\n") @staticmethod def save_jsonlist(file_path: str, json_list: List, mode: str = "a"): """ 將JSON對象列表保存到JSONL文件中。 :param file_path: JSONL文件路徑 :param json_list: JSON對象列表 :param mode: 文件寫入模式 """ with open(file_path, mode) as file_obj: for json_obj in json_list: json_str = json.dumps(json_obj, default=str) file_obj.write(json_str + "\n") @staticmethod def str_list_to_dir_path(str_list: List[str]) -> str: """ 將字符串列表拼接為目錄路徑。 :param str_list: 字符串列表 :return: 拼接后的目錄路徑 """ if not str_list: return "" dir_path = "" for dir_name in str_list: dir_path = join(dir_path, dir_name) return dir_path # 示例類 class Config: def __init__(self, name, value, description=None): self.name = name self.value = value self.description = description # 示例1: 將YAML文件轉(zhuǎn)換為字典 yaml_dict = Utils.yaml_to_dict("config.yaml") print("YAML文件轉(zhuǎn)換為字典:", yaml_dict) # 示例2: 將YAML文件轉(zhuǎn)換為類對象 config_obj = Utils.yaml_to_class("config.yaml", Config, "default_config.yaml") print("YAML文件轉(zhuǎn)換為類對象:", config_obj.name, config_obj.value, config_obj.description) # 示例3: 讀取JSONL文件 jsonl_list = Utils.read_jsonl("data.jsonl") print("讀取JSONL文件:", jsonl_list) # 示例4: 逐行讀取JSONL文件 print("逐行讀取JSONL文件:") for json_obj in Utils.read_jsonl_row("data.jsonl"): print(json_obj) # 示例5: 將字典追加到JSONL文件 Utils.append_as_jsonl("data.jsonl", {"id": 4, "name": "David", "age": 40}) print("追加數(shù)據(jù)到JSONL文件完成") # 示例6: 將JSON對象列表保存到JSONL文件 Utils.save_jsonlist("data.jsonl", [{"id": 5, "name": "Eve", "age": 45}]) print("保存JSON列表到JSONL文件完成") # 示例7: 將字符串列表拼接為目錄路徑 path = Utils.str_list_to_dir_path(["dir1", "dir2", "dir3"]) print("拼接目錄路徑:", path)
7. 總結(jié)
通過將特定的異常類改寫為通用的ValidationException,并創(chuàng)建一個包含常用方法的Utils工具類,我們可以大大提高代碼的復(fù)用性和可維護(hù)性。本文提供的代碼示例展示了如何使用這些工具類進(jìn)行文件操作和數(shù)據(jù)處理,適合初級Python程序員學(xué)習(xí)和參考。
到此這篇關(guān)于詳解Python中通用工具類與異常處理的文章就介紹到這了,更多相關(guān)Python通用工具類與異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)的多進(jìn)程和多線程功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)的多進(jìn)程和多線程功能,結(jié)合實(shí)例形式分析了Python多線程與多進(jìn)程實(shí)現(xiàn)分布式系統(tǒng)功能相關(guān)操作技巧,需要的朋友可以參考下2018-05-05基于Python實(shí)現(xiàn)簡易學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡易學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07如何實(shí)現(xiàn)在pycharm中將.ui文件轉(zhuǎn)化為.py文件
這篇文章主要介紹了如何實(shí)現(xiàn)在pycharm中將.ui文件轉(zhuǎn)化為.py文件,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06python利用paramiko連接遠(yuǎn)程服務(wù)器執(zhí)行命令的方法
下面小編就為大家?guī)硪黄猵ython利用paramiko連接遠(yuǎn)程服務(wù)器執(zhí)行命令的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10使用Python實(shí)現(xiàn)Excel文件轉(zhuǎn)換為SVG格式
SVG(Scalable Vector Graphics)是一種基于XML的矢量圖像格式,這種格式在Web開發(fā)和其他圖形應(yīng)用中非常流行,提供了一種高效的方式來呈現(xiàn)復(fù)雜的矢量圖形,本文將介紹如何使用Python轉(zhuǎn)換Excel文件為SVG格式,需要的朋友可以參考下2024-07-07Python簡單實(shí)現(xiàn)enum功能的方法
這篇文章主要介紹了Python簡單實(shí)現(xiàn)enum功能的方法,簡單分析了Python實(shí)現(xiàn)enum功能的相關(guān)技巧,需要的朋友可以參考下2016-04-04關(guān)于Python中*args和**kwargs的深入理解
這篇文章主要給大家介紹了關(guān)于Python中*args和**kwargs的相關(guān)資料,*args和**kwargs代表的是變量, 變量前面的 *(星號)才是必須的,也可以寫成*v和**vs;寫成*args和**kwargs只是一個常用的書寫方式,需要的朋友可以參考下2021-08-08[項目布局配置]Nosql與PythonWeb-Flask框架組合
本文主要描述了怎樣使用輕量級NoSQL數(shù)據(jù)庫與PythonWeb-Flask框架組合來進(jìn)行項目布局及應(yīng)用配置,需要的同學(xué)可以參考下,希望可以對大家有所進(jìn)益2021-08-08