# -*- coding: utf-8 -*- """ 规则引擎 """ from datetime import datetime from decimal import Decimal from pathlib import Path from typing import Any, Dict, Union from zen import ZenDecision, ZenEngine class RulesEngine: """ 规则引擎,支持: evaluate:调用并返回评估结果 """ def __init__(self, decisions_folder_path: Path): """ 初始化规则引擎 :param decisions_folder_path: 决策文件夹路径 """ decisions_folder_path.mkdir(exist_ok=True) # 若规则文件夹不存在则创建 # 初始化决策缓存 self.decisions = {} for decision_path in decisions_folder_path.glob("*.json"): # 打开并读取决策文件并实例化 ZenDecision self.decisions[decision_path.stem] = self._get_decision(decision_path) @staticmethod def _get_decision(decision_path: Path) -> ZenDecision: """ 打开并读取决策文件并实例化 ZenDecision :param decision_path: 决策文件路径 :return: 实例化 ZenDecision """ def loader(path): with open(path, "r", encoding="utf-8") as file: return file.read() return ZenEngine({"loader": loader}).get_decision(decision_path.as_posix()) def evaluate(self, decision: str, inputs: Dict[str, Any]) -> Dict[str, Any]: """ 调用决策并返回评估结果 :param decision: 决策名称 :param inputs: 待评估对象 :return: 评估结果 """ return self.decisions[decision].evaluate(self._formatter(inputs))["result"] def _formatter( self, inputs: Union[str, int, Decimal, datetime, list, dict, Any] ) -> Any: """ 格式化器 :param inputs: 待评估对象 :return: 格式化后待评估对象 """ match inputs: case int(): return str(inputs) case Decimal(): return format(inputs, ".2f") case datetime(): return inputs.strftime("%Y-%m-%d %H:%M:%S") case list(): return [self._formatter(i) for i in inputs] case dict(): return { key: self._formatter(value) for key, value in inputs.items() } # 递归格式化 case _: return inputs