Archived
0
0

fix: 增加日志

This commit is contained in:
2025-12-15 15:39:05 +08:00
parent 874494874c
commit 6efd041f72
51 changed files with 635 additions and 1992 deletions

View File

@@ -4,6 +4,10 @@ Particle 模块 - 粒子对象系统
提供闪卡所需对象, 使用物理学粒子的领域驱动设计
"""
from heurams.services.logger import get_logger
logger = get_logger(__name__)
logger.debug("粒子模块已加载")
from .electron import Electron
from .nucleon import Nucleon
from .orbital import Orbital

View File

@@ -8,6 +8,9 @@ import toml
import json
import bidict
from heurams.context import config_var
from heurams.services.logger import get_logger
logger = get_logger(__name__)
class AtomRegister(TypedDict):
@@ -33,8 +36,10 @@ class Atom:
"""
def __init__(self, ident=""):
logger.debug("创建 Atom 实例ident: '%s'", ident)
self.ident = ident
atom_registry[ident] = self
logger.debug("Atom 已注册到全局注册表,当前注册表大小: %d", len(atom_registry))
# self.is_evaled = False
self.registry: AtomRegister = { # type: ignore
"nucleon": None,
@@ -48,12 +53,16 @@ class Atom:
"orbital_fmt": "toml",
}
self.do_eval()
logger.debug("Atom 初始化完成")
def link(self, key, value):
logger.debug("Atom.link: key='%s', value type: %s", key, type(value).__name__)
if key in self.registry.keys():
self.registry[key] = value
logger.debug("'%s' 已链接,触发 do_eval", key)
self.do_eval()
else:
logger.error("尝试链接不受支持的键: '%s'", key)
raise ValueError("不受支持的原子元数据链接操作")
def do_eval(self):
@@ -61,6 +70,7 @@ class Atom:
执行并以结果替换当前单元的所有 eval 语句
TODO: 带有限制的 eval, 异步/多线程执行避免堵塞
"""
logger.debug("Atom.do_eval 开始")
# eval 环境设置
def eval_with_env(s: str):
@@ -72,8 +82,10 @@ class Atom:
ret = "尚未链接对象"
try:
ret = str(eval(s))
logger.debug("eval 执行成功: '%s' -> '%s'", s, ret[:50] + '...' if len(ret) > 50 else ret)
except Exception as e:
ret = f"此 eval 实例发生错误: {e}"
logger.warning("eval 执行错误: '%s' -> %s", s, e)
return ret
def traverse(data, modifier):
@@ -90,37 +102,52 @@ class Atom:
else:
if isinstance(data, str):
if data.startswith("eval:"):
logger.debug("发现 eval 表达式: '%s'", data[5:])
return modifier(data[5:])
return data
traverse(self.registry["nucleon"], eval_with_env)
traverse(self.registry["orbital"], eval_with_env)
logger.debug("Atom.do_eval 完成")
def persist(self, key):
logger.debug("Atom.persist: key='%s'", key)
path: pathlib.Path | None = self.registry[key + "_path"]
if isinstance(path, pathlib.Path):
path = typing.cast(pathlib.Path, path)
logger.debug("持久化路径: %s, 格式: %s", path, self.registry[key + "_fmt"])
path.parent.mkdir(parents=True, exist_ok=True)
if self.registry[key + "_fmt"] == "toml":
with open(path, "w") as f:
toml.dump(self.registry[key], f)
logger.debug("TOML 数据已保存到: %s", path)
elif self.registry[key + "_fmt"] == "json":
with open(path, "w") as f:
json.dump(self.registry[key], f)
logger.debug("JSON 数据已保存到: %s", path)
else:
logger.error("不受支持的持久化格式: %s", self.registry[key + "_fmt"])
raise KeyError("不受支持的持久化格式")
else:
logger.error("路径未初始化: %s_path", key)
raise TypeError("对未初始化的路径对象操作")
def __getitem__(self, key):
logger.debug("Atom.__getitem__: key='%s'", key)
if key in self.registry:
return self.registry[key]
value = self.registry[key]
logger.debug("返回 value type: %s", type(value).__name__)
return value
logger.error("不支持的键: '%s'", key)
raise KeyError(f"不支持的键: {key}")
def __setitem__(self, key, value):
logger.debug("Atom.__setitem__: key='%s', value type: %s", key, type(value).__name__)
if key in self.registry:
self.registry[key] = value
logger.debug("'%s' 已设置", key)
else:
logger.error("不支持的键: '%s'", key)
raise KeyError(f"不支持的键: {key}")
@staticmethod

View File

@@ -1,6 +1,9 @@
import heurams.services.timer as timer
from heurams.context import config_var
from heurams.kernel.algorithms import algorithms
from heurams.services.logger import get_logger
logger = get_logger(__name__)
class Electron:
@@ -14,45 +17,69 @@ class Electron:
algodata: 算法数据字典, 包含算法的各项参数和设置
algo: 使用的算法模块标识
"""
logger.debug("创建 Electron 实例ident: '%s', algo_name: '%s'", ident, algo_name)
self.algodata = algodata
self.ident = ident
self.algo = algorithms[algo_name]
logger.debug("使用的算法类: %s", self.algo.__name__)
if self.algo not in self.algodata.keys():
self.algodata[self.algo] = {}
logger.debug("算法键 '%s' 不存在,已创建空字典", self.algo)
if not self.algodata[self.algo]:
logger.debug("算法数据为空,使用默认值初始化")
self._default_init(self.algo.defaults)
else:
logger.debug("算法数据已存在,跳过默认初始化")
logger.debug("Electron 初始化完成algodata keys: %s", list(self.algodata.keys()))
def _default_init(self, defaults: dict):
"""默认初始化包装"""
logger.debug("Electron._default_init: 使用默认值keys: %s", list(defaults.keys()))
self.algodata[self.algo] = defaults.copy()
def activate(self):
"""激活此电子"""
logger.debug("Electron.activate: 激活 ident='%s'", self.ident)
self.algodata[self.algo]["is_activated"] = 1
self.algodata[self.algo]["last_modify"] = timer.get_timestamp()
logger.debug("电子已激活is_activated=1")
def modify(self, var: str, value):
"""修改 algodata[algo] 中子字典数据"""
logger.debug("Electron.modify: var='%s', value=%s", var, value)
if var in self.algodata[self.algo]:
self.algodata[self.algo][var] = value
self.algodata[self.algo]["last_modify"] = timer.get_timestamp()
logger.debug("变量 '%s' 已修改,更新 last_modify", var)
else:
logger.warning("'%s' 非已知元数据字段", var)
print(f"警告: '{var}' 非已知元数据字段")
def is_due(self):
"""是否应该复习"""
return self.algo.is_due(self.algodata)
logger.debug("Electron.is_due: 检查 ident='%s'", self.ident)
result = self.algo.is_due(self.algodata)
logger.debug("is_due 结果: %s", result)
return result
def is_activated(self):
return self.algodata[self.algo]["is_activated"]
result = self.algodata[self.algo]["is_activated"]
logger.debug("Electron.is_activated: ident='%s', 结果: %d", self.ident, result)
return result
def rate(self):
"评价"
return self.algo.rate(self.algodata)
logger.debug("Electron.rate: ident='%s'", self.ident)
result = self.algo.rate(self.algodata)
logger.debug("rate 结果: %s", result)
return result
def nextdate(self) -> int:
return self.algo.nextdate(self.algodata)
logger.debug("Electron.nextdate: ident='%s'", self.ident)
result = self.algo.nextdate(self.algodata)
logger.debug("nextdate 结果: %d", result)
return result
def revisor(self, quality: int = 5, is_new_activation: bool = False):
"""算法迭代决策机制实现
@@ -61,7 +88,10 @@ class Electron:
quality (int): 记忆保留率量化参数 (0-5)
is_new_activation (bool): 是否为初次激活
"""
logger.debug("Electron.revisor: ident='%s', quality=%d, is_new_activation=%s",
self.ident, quality, is_new_activation)
self.algo.revisor(self.algodata, quality, is_new_activation)
logger.debug("revisor 完成,更新后的 algodata: %s", self.algodata.get(self.algo, {}))
def __str__(self):
return (

View File

@@ -5,12 +5,17 @@ import pathlib
import toml
import json
from copy import deepcopy
from heurams.services.logger import get_logger
logger = get_logger(__name__)
def load_nucleon(path: pathlib.Path, fmt="toml"):
logger.debug("load_nucleon: 加载文件 %s, 格式: %s", path, fmt)
with open(path, "r") as f:
dictdata = dict()
dictdata = toml.load(f) # type: ignore
logger.debug("TOML 解析成功keys: %s", list(dictdata.keys()))
lst = list()
nested_data = dict()
# 修正 toml 解析器的不管嵌套行为
@@ -24,12 +29,15 @@ def load_nucleon(path: pathlib.Path, fmt="toml"):
current[part] = {}
current = current[part]
current[parts[-1]] = value
logger.debug("处理元数据键: %s", key)
else:
nested_data[key] = value
logger.debug("嵌套数据处理完成keys: %s", list(nested_data.keys()))
# print(nested_data)
for item, attr in nested_data.items():
if item == "__metadata__":
continue
logger.debug("处理项目: %s", item)
lst.append(
(
Nucleon(
@@ -38,6 +46,7 @@ def load_nucleon(path: pathlib.Path, fmt="toml"):
deepcopy(nested_data["__metadata__"]["orbital"]),
)
)
logger.debug("load_nucleon 完成,加载了 %d 个 Nucleon 对象", len(lst))
return lst
@@ -51,10 +60,14 @@ def load_electron(path: pathlib.Path, fmt="json") -> dict:
Returns:
dict: 键名是电子对象名称, 值是电子对象
"""
logger.debug("load_electron: 加载文件 %s, 格式: %s", path, fmt)
with open(path, "r") as f:
dictdata = dict()
dictdata = json.load(f) # type: ignore
logger.debug("JSON 解析成功keys: %s", list(dictdata.keys()))
dic = dict()
for item, attr in dictdata.items():
logger.debug("处理电子项目: %s", item)
dic[item] = Electron(hasher.hash(item), attr)
logger.debug("load_electron 完成,加载了 %d 个 Electron 对象", len(dic))
return dic

View File

@@ -1,3 +1,8 @@
from heurams.services.logger import get_logger
logger = get_logger(__name__)
class Nucleon:
"""原子核: 材料元数据"""
@@ -9,16 +14,24 @@ class Nucleon:
payload: 记忆内容信息
metadata: 可选元数据信息
"""
logger.debug("创建 Nucleon 实例ident: '%s', payload keys: %s, metadata keys: %s",
ident, list(payload.keys()) if payload else [], list(metadata.keys()) if metadata else [])
self.metadata = metadata
self.payload = payload
self.ident = ident
logger.debug("Nucleon 初始化完成")
def __getitem__(self, key):
logger.debug("Nucleon.__getitem__: key='%s'", key)
if key == "ident":
logger.debug("返回 ident: '%s'", self.ident)
return self.ident
if key in self.payload:
return self.payload[key]
value = self.payload[key]
logger.debug("返回 payload['%s'], value type: %s", key, type(value).__name__)
return value
else:
logger.error("'%s' 未在 payload 中找到", key)
raise KeyError(f"Key '{key}' not found in payload.")
def __iter__(self):
@@ -35,14 +48,17 @@ class Nucleon:
执行并以结果替换当前单元的所有 eval 语句
TODO: 带有限制的 eval, 异步/多线程执行避免堵塞
"""
logger.debug("Nucleon.do_eval 开始")
# eval 环境设置
def eval_with_env(s: str):
try:
nucleon = self
ret = str(eval(s))
logger.debug("eval 执行成功: '%s' -> '%s'", s, ret[:50] + '...' if len(ret) > 50 else ret)
except Exception as e:
ret = f"此 eval 实例发生错误: {e}"
logger.warning("eval 执行错误: '%s' -> %s", s, e)
return ret
def traverse(data, modifier):
@@ -59,13 +75,16 @@ class Nucleon:
else:
if isinstance(data, str):
if data.startswith("eval:"):
logger.debug("发现 eval 表达式: '%s'", data[5:])
return modifier(data[5:])
return data
traverse(self.payload, eval_with_env)
traverse(self.metadata, eval_with_env)
logger.debug("Nucleon.do_eval 完成")
@staticmethod
def placeholder():
"""生成一个占位原子核"""
logger.debug("创建 Nucleon 占位符")
return Nucleon("核子对象样例内容", {})

View File

@@ -1,4 +1,8 @@
from typing import TypedDict
from heurams.services.logger import get_logger
logger = get_logger(__name__)
logger.debug("Orbital 类型定义模块已加载")
class OrbitalSchedule(TypedDict):

View File

@@ -1,17 +1,26 @@
from heurams.context import config_var
import pathlib
from heurams.services.logger import get_logger
logger = get_logger(__name__)
def probe_by_filename(filename):
"""探测指定文件 (无扩展名) 的所有信息"""
logger.debug("probe_by_filename: 探测文件 '%s'", filename)
paths: dict = config_var.get().get("paths")
logger.debug("配置路径: %s", paths)
formats = ["toml", "json"]
result = {}
for item, attr in paths.items():
for i in formats:
attr: pathlib.Path = pathlib.Path(attr) / filename + "." + i
if attr.exists():
logger.debug("找到文件: %s", attr)
result[item.replace("_dir", "")] = str(attr)
else:
logger.debug("文件不存在: %s", attr)
logger.debug("probe_by_filename 结果: %s", result)
return result
@@ -24,17 +33,24 @@ def probe_all(is_stem=1):
Returns:
dict: 有三项, 每一项的键名都是文件组类型, 值都是文件组列表, 只包含文件名
"""
logger.debug("probe_all: 开始探测is_stem=%d", is_stem)
paths: dict = config_var.get().get("paths")
logger.debug("配置路径: %s", paths)
result = {}
for item, attr in paths.items():
attr: pathlib.Path = pathlib.Path(attr)
result[item.replace("_dir", "")] = list()
logger.debug("扫描目录: %s", attr)
file_count = 0
for i in attr.iterdir():
if not i.is_dir():
file_count += 1
if is_stem:
result[item.replace("_dir", "")].append(str(i.stem))
else:
result[item.replace("_dir", "")].append(str(i.name))
logger.debug("目录 %s 中找到 %d 个文件", attr, file_count)
logger.debug("probe_all 完成,结果 keys: %s", list(result.keys()))
return result