79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
# -*- 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
|