BS 0.1.0
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
[返回](./Runtime-README.md)
|
||||
|
||||
# /Convention/Runtime/Config
|
||||
|
||||
---
|
||||
|
||||
包含了关于静态的配置信息等内容, 并且引入全体标准库内容
|
||||
|
||||
## Import All
|
||||
|
||||
检查并尝试引入所有依赖库
|
||||
|
||||
## 静态配置
|
||||
|
||||
若不存在相应配置, 则需要定义
|
||||
|
||||
- `CURRENT_COM_NAME` 公司/组织名称
|
||||
- `CURRENT_APP_NAME` 应用名称
|
||||
|
||||
## PlatformIndicator包含的内容
|
||||
|
||||
- `IsRelease` Debug/Release状态
|
||||
- `IsPlatform<Name>` 平台判断
|
||||
- `IsPlatformX64`平台架构判断
|
||||
- 编译器/解释器判断 如`IsMSVC`等
|
||||
- `ApplicationPath` 获取当前应用程序目录
|
||||
- `StreamingAssetsPath` 获取StreamingAssets目录
|
||||
- `PersistentPath` 获取持久化目录
|
||||
- `PlatformInfomation` 平台相关的发布信息
|
||||
|
||||
## 多个静态类 <Type>Indicator
|
||||
|
||||
包含对应类型常用的工具函数
|
||||
|
||||
## 静态类 DescriptiveIndicator
|
||||
|
||||
包含一个`描述`字符串, 可选一个`值`对象
|
||||
|
||||
## 其他基础内容
|
||||
|
||||
用于对齐不同语言间基本实现的颗粒度, 如以下内容
|
||||
|
||||
- 类型转换
|
||||
- 字符串操作
|
||||
- Construct/Destruct 重构造/析构
|
||||
- 命令行解析
|
||||
- 简单的反射内容
|
||||
- 元类型
|
||||
- 等等...
|
@@ -121,13 +121,13 @@ class ActionEvent[_Call:Callable]:
|
||||
return ex
|
||||
def CallFunc(self, index:int, *args, **kwargs) -> Union[Any, Exception]:
|
||||
return self.CallFuncWithoutCallIndexControl(self.call_indexs[index], *args, **kwargs)
|
||||
def _inject_invoke(self, *args, **kwargs):
|
||||
def _InjectInvoke(self, *args, **kwargs):
|
||||
result:List[Any] = []
|
||||
for index in range(self.call_max_count):
|
||||
for index in range(self.CallMaxCount):
|
||||
result.append(self.CallFunc(index, *args, **kwargs))
|
||||
return result
|
||||
def Invoke(self, *args, **kwargs) -> Union[Self, bool]:
|
||||
self.last_result = self._inject_invoke(*args, **kwargs)
|
||||
self.last_result = self._InjectInvoke(*args, **kwargs)
|
||||
return self
|
||||
def InitCallIndex(self):
|
||||
self.call_indexs = [i for i in range(len(self.__actions))]
|
||||
@@ -247,6 +247,10 @@ class lock_guard:
|
||||
self._locker.acquire()
|
||||
def __del__(self):
|
||||
self._locker.release()
|
||||
def __enter__(self):
|
||||
return
|
||||
def __exit__(self,*args,**kwargs):
|
||||
return True
|
||||
|
||||
class global_lock_guard(lock_guard):
|
||||
def __init__(self):
|
||||
@@ -276,3 +280,63 @@ def Nowf() -> str:
|
||||
return: str
|
||||
'''
|
||||
return datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||
|
||||
true: Literal[True] = True
|
||||
false: Literal[False] = False
|
||||
|
||||
class PlatformIndicator:
|
||||
IsRelease : bool = False
|
||||
IsPlatformWindows : bool = sys.platform == "Windows"
|
||||
IsPlatformLinux : bool = sys.platform == "Linux"
|
||||
IsPlatformOsx : bool = sys.platform == "OSX"
|
||||
IsPlatformX64 : bool = True
|
||||
CompanyName : str = "DefaultCompany"
|
||||
ProductName : str = "DefaultProject"
|
||||
|
||||
@staticmethod
|
||||
def GetApplicationPath() -> str:
|
||||
"""获取应用程序所在目录"""
|
||||
import os
|
||||
return os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
@staticmethod
|
||||
def GetCurrentWorkingDirectory() -> str:
|
||||
"""获取当前工作目录"""
|
||||
import os
|
||||
return os.getcwd()
|
||||
|
||||
# 使用类方法获取路径
|
||||
@classmethod
|
||||
def ApplicationPath(cls) -> str:
|
||||
"""应用程序路径属性"""
|
||||
return cls.GetApplicationPath()
|
||||
|
||||
@classmethod
|
||||
def StreamingAssetsPath(cls) -> str:
|
||||
"""流媒体资源路径属性"""
|
||||
return cls.ApplicationPath() + "/StreamingAssets/"
|
||||
|
||||
@staticmethod
|
||||
def PersistentDataPath() -> str:
|
||||
"""
|
||||
获取持久化数据路径,根据平台返回不同的路径
|
||||
"""
|
||||
import os
|
||||
if PlatformIndicator.IsPlatformWindows:
|
||||
return os.path.expandvars(f"%userprofile%\\AppData\\LocalLow\\{PlatformIndicator.CompanyName}\\{PlatformIndicator.ProductName}\\")
|
||||
elif PlatformIndicator.IsPlatformLinux:
|
||||
return os.path.expandvars("$HOME/.config/")
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def DataPath() -> str:
|
||||
"""
|
||||
获取数据路径
|
||||
"""
|
||||
return "Assets/"
|
||||
|
||||
class DescriptiveIndicator[T]:
|
||||
def __init__(self, description:str, value:T) -> None:
|
||||
self.descripion : str = description
|
||||
self.value : T = value
|
||||
|
||||
|
408
Convention/Runtime/EasySave.py
Normal file
408
Convention/Runtime/EasySave.py
Normal file
@@ -0,0 +1,408 @@
|
||||
from .Reflection import *
|
||||
from .File import ToolFile
|
||||
from .String import LimitStringLength
|
||||
|
||||
_Internal_EasySave_Debug:bool = False
|
||||
def GetInternalEasySaveDebug() -> bool:
|
||||
return _Internal_EasySave_Debug and GetInternalDebug()
|
||||
def SetInternalEasySaveDebug(debug:bool) -> None:
|
||||
global _Internal_EasySave_Debug
|
||||
_Internal_EasySave_Debug = debug
|
||||
|
||||
class EasySaveSetting(BaseModel, any_class):
|
||||
key: str = Field(description="目标键", default="easy")
|
||||
# 从目标文件进行序列化/反序列化
|
||||
file: str = Field(description="目标文件")
|
||||
# 序列化/反序列化的格式方法
|
||||
format: Literal["json", "binary"] = Field(description="保存模式", default="json")
|
||||
# TODO: refChain: bool = Field(description="是否以保留引用的方式保存", default=True)
|
||||
# 文件形式与参数
|
||||
# TODO: encoding: str = Field(description="编码", default="utf-8")
|
||||
is_backup: bool = Field(description="是否备份", default=True)
|
||||
backup_suffix: str = Field(description="备份后缀", default=".backup")
|
||||
# 序列化/反序列化时, 如果设置了忽略字段的谓词, 则被谓词选中的字段将不会工作
|
||||
# 如果设置了选择字段的谓词, 则被选中的字段才会工作
|
||||
ignore_pr: Optional[Callable[[FieldInfo], bool]] = Field(description="忽略字段的谓词", default=None)
|
||||
select_pr: Optional[Callable[[FieldInfo], bool]] = Field(description="选择字段的谓词", default=None)
|
||||
|
||||
class ESWriter(BaseModel, any_class):
|
||||
setting: EasySaveSetting = Field(description="设置")
|
||||
|
||||
@sealed
|
||||
def _GetFields(self, rtype:RefType) -> List[FieldInfo]:
|
||||
'''
|
||||
获取字段
|
||||
'''
|
||||
fields: List[FieldInfo] = []
|
||||
if self.setting.ignore_pr is not None and self.setting.select_pr is not None:
|
||||
fields = [ field for field in rtype.GetAllFields() if self.setting.select_pr(field) and not self.setting.ignore_pr(field) ]
|
||||
elif self.setting.select_pr is None and self.setting.ignore_pr is None:
|
||||
fields = rtype.GetFields()
|
||||
elif self.setting.ignore_pr is not None:
|
||||
fields = [ field for field in rtype.GetAllFields() if not self.setting.ignore_pr(field) ]
|
||||
else:
|
||||
fields = [ field for field in rtype.GetAllFields() if self.setting.select_pr(field) ]
|
||||
return fields
|
||||
|
||||
@sealed
|
||||
def _DoJsonSerialize(self, result_file:ToolFile, rtype:RefType, rinstance:Any) -> Any:
|
||||
'''
|
||||
序列化: json格式
|
||||
'''
|
||||
|
||||
def dfs(rtype:RefType, rinstance:Any) -> Dict[str, Any]|Any:
|
||||
if rinstance is None:
|
||||
return rinstance
|
||||
|
||||
if rtype.IsUnion:
|
||||
rtype = TypeManager.GetInstance().CreateOrGetRefType(rinstance)
|
||||
|
||||
if rtype.IsValueType:
|
||||
return rinstance
|
||||
elif rtype.IsCollection:
|
||||
try:
|
||||
if rtype.IsList:
|
||||
return [ dfs(TypeManager.GetInstance().CreateOrGetRefType(iter_), iter_) for iter_ in rinstance ]
|
||||
elif rtype.IsSet:
|
||||
return { dfs(TypeManager.GetInstance().CreateOrGetRefType(iter_), iter_) for iter_ in rinstance }
|
||||
elif rtype.IsTuple:
|
||||
return tuple(dfs(TypeManager.GetInstance().CreateOrGetRefType(iter_), iter_) for iter_ in rinstance)
|
||||
elif rtype.IsDictionary:
|
||||
return {
|
||||
dfs(TypeManager.GetInstance().CreateOrGetRefType(key), key):
|
||||
dfs(TypeManager.GetInstance().CreateOrGetRefType(iter_), iter_)
|
||||
for key, iter_ in rinstance.items()
|
||||
}
|
||||
except Exception as e:
|
||||
raise ReflectionException(f"{ConsoleFrontColor.RED}容器<{rtype.RealType}>"\
|
||||
f"在序列化时遇到错误:{ConsoleFrontColor.RESET}\n{e}") from e
|
||||
raise NotImplementedError(f"{ConsoleFrontColor.RED}不支持的容器: {rinstance}"\
|
||||
f"<{rtype.print_str(verbose=GetInternalEasySaveDebug())}>{ConsoleFrontColor.RESET}")
|
||||
elif hasattr(rtype.RealType, "__easy_serialize__"):
|
||||
custom_data, is_need_type = rtype.RealType.__easy_serialize__(rinstance)
|
||||
if is_need_type:
|
||||
return {
|
||||
"__type": AssemblyTypen(rtype.RealType),
|
||||
**custom_data
|
||||
}
|
||||
else:
|
||||
return custom_data
|
||||
else:
|
||||
fields: List[FieldInfo] = self._GetFields(rtype)
|
||||
layer: Dict[str, Any] = {
|
||||
"__type": AssemblyTypen(rtype.RealType)
|
||||
}
|
||||
for field in fields:
|
||||
try:
|
||||
layer[field.FieldName] = dfs(
|
||||
TypeManager.GetInstance().CreateOrGetRefType(field.FieldType),
|
||||
field.GetValue(rinstance)
|
||||
)
|
||||
except Exception as e:
|
||||
raise ReflectionException(f"{ConsoleFrontColor.RED}字段{field.FieldName}"\
|
||||
f"<{field.FieldType}>在序列化时遇到错误:{ConsoleFrontColor.RESET}\n{e}") from e
|
||||
return layer
|
||||
|
||||
layers: Dict[str, Any] = {}
|
||||
if result_file.exists():
|
||||
filedata = result_file.load()
|
||||
if isinstance(filedata, dict):
|
||||
layers = filedata
|
||||
layers[self.setting.key] = {
|
||||
"__type": AssemblyTypen(rtype.RealType),
|
||||
"value": dfs(rtype, rinstance)
|
||||
}
|
||||
result_file.data = layers
|
||||
result_file.save_as_json()
|
||||
|
||||
@sealed
|
||||
def _DoBinarySerialize(self, result_file:ToolFile, rinstance:Any) -> Any:
|
||||
'''
|
||||
序列化: 二进制格式
|
||||
'''
|
||||
result_file.data = rinstance
|
||||
result_file.save_as_binary()
|
||||
|
||||
@virtual
|
||||
def Serialize(self, result_file:ToolFile, rtype:RefType, rinstance:Any) -> Any:
|
||||
'''
|
||||
序列化
|
||||
'''
|
||||
if self.setting.format == "json":
|
||||
self._DoJsonSerialize(result_file, rtype, rinstance)
|
||||
elif self.setting.format == "binary":
|
||||
self._DoBinarySerialize(result_file, rinstance)
|
||||
else:
|
||||
raise NotImplementedError(f"不支持的格式: {self.setting.format}")
|
||||
|
||||
@virtual
|
||||
def Write[T](self, rinstance:T) -> ToolFile:
|
||||
'''
|
||||
写入数据
|
||||
'''
|
||||
result_file: ToolFile = ToolFile(self.setting.file)
|
||||
backup_file: ToolFile = None
|
||||
if result_file.dirpath is not None and not ToolFile(result_file.dirpath).exists():
|
||||
raise FileNotFoundError(f"文件路径不存在: {result_file.dirpath}")
|
||||
if result_file.exists() and self.setting.is_backup:
|
||||
if result_file.dirpath is not None:
|
||||
backup_file = result_file.dirpath | (result_file.get_filename(True) + self.setting.backup_suffix)
|
||||
else:
|
||||
backup_file = ToolFile(result_file.get_filename(True) + self.setting.backup_suffix)
|
||||
result_file.copy(backup_file)
|
||||
try:
|
||||
self.Serialize(result_file, TypeManager.GetInstance().CreateOrGetRefType(rinstance), rinstance)
|
||||
except Exception:
|
||||
if backup_file is not None:
|
||||
result_file.remove()
|
||||
backup_file.copy(result_file)
|
||||
backup_file.remove()
|
||||
raise
|
||||
finally:
|
||||
if backup_file is not None:
|
||||
backup_file.remove()
|
||||
return result_file
|
||||
|
||||
class ESReader(BaseModel, any_class):
|
||||
setting: EasySaveSetting = Field(description="设置")
|
||||
|
||||
@sealed
|
||||
def _GetFields(self, rtype:RefType) -> List[FieldInfo]:
|
||||
'''
|
||||
获取字段
|
||||
'''
|
||||
fields: List[FieldInfo] = []
|
||||
if self.setting.ignore_pr is not None and self.setting.select_pr is not None:
|
||||
fields = [ field for field in rtype.GetAllFields() if self.setting.select_pr(field) and not self.setting.ignore_pr(field) ]
|
||||
elif self.setting.select_pr is None and self.setting.ignore_pr is None:
|
||||
fields = rtype.GetFields()
|
||||
elif self.setting.ignore_pr is not None:
|
||||
fields = [ field for field in rtype.GetAllFields() if not self.setting.ignore_pr(field) ]
|
||||
else:
|
||||
fields = [ field for field in rtype.GetAllFields() if self.setting.select_pr(field) ]
|
||||
return fields
|
||||
|
||||
def get_rtype_from_typen(self, type_label:str) -> RefType:
|
||||
'''
|
||||
从类型标签中获取类型
|
||||
'''
|
||||
#module_name, _, class_name = type_label.split(",")[0].strip().rpartition('.')
|
||||
#if GetInternalEasySaveDebug():
|
||||
# print_colorful(ConsoleFrontColor.YELLOW, f"Prase __type label: {ConsoleFrontColor.RESET}{type_label}"\
|
||||
# f"{ConsoleFrontColor.YELLOW}, module_name: {ConsoleFrontColor.RESET}{module_name}"\
|
||||
# f"{ConsoleFrontColor.YELLOW}, class_name: {ConsoleFrontColor.RESET}{class_name}")
|
||||
#typen_to = try_to_type(class_name, module_name=module_name) or to_type(class_name)
|
||||
#return TypeManager.GetInstance().CreateOrGetRefType(typen_to)
|
||||
typen, assembly_name = ReadAssemblyTypen(type_label)
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"Prase __type label: {ConsoleFrontColor.RESET}{type_label}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, typen: {ConsoleFrontColor.RESET}{typen}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, assembly_name: {ConsoleFrontColor.RESET}{assembly_name}")
|
||||
return TypeManager.GetInstance().CreateOrGetRefType(typen)
|
||||
|
||||
@sealed
|
||||
def _DoJsonDeserialize(self, read_file:ToolFile, rtype:Optional[RefType] = None) -> Any:
|
||||
'''
|
||||
反序列化: json格式
|
||||
|
||||
Args:
|
||||
read_file (ToolFile): 要读取的文件对象
|
||||
rtype (Optional[RTypen[Any]], optional): 目标类型. 如果为None, 则从文件中读取类型信息. Defaults to None.
|
||||
|
||||
Returns:
|
||||
Any: 反序列化后的对象
|
||||
|
||||
Raises:
|
||||
NotImplementedError: 当遇到不支持的集合类型时抛出
|
||||
ValueError: 当rinstance不为None时抛出
|
||||
'''
|
||||
# 从文件中加载JSON数据
|
||||
layers: Dict[str, Any] = read_file.load_as_json()
|
||||
if self.setting.key not in layers:
|
||||
raise ValueError(f"{ConsoleFrontColor.RED}文件中不包含目标键: {ConsoleFrontColor.RESET}{self.setting.key}")
|
||||
# 如果未指定类型, 则从JSON数据中获取类型信息
|
||||
if rtype is None:
|
||||
rtype: RefType = self.get_rtype_from_typen(layers["__type"])
|
||||
layers: Dict[str, Any] = layers[self.setting.key]["value"]
|
||||
result_instance: Any = None
|
||||
|
||||
def dfs(rtype:Optional[RefType], layer:Dict[str, Any]|Any) -> Any:
|
||||
'''
|
||||
深度优先遍历反序列化
|
||||
|
||||
Args:
|
||||
rtype (Optional[RefType]): 当前处理的类型
|
||||
layer (Dict[str, Any]|Any): 当前处理的JSON数据层
|
||||
rinstance (Any): 当前处理的对象实例
|
||||
|
||||
Returns:
|
||||
Any: 反序列化后的对象
|
||||
'''
|
||||
# 如果类型为None且当前层包含类型信息, 则获取类型
|
||||
if isinstance(layer, dict) and "__type" in layer:
|
||||
rtype = self.get_rtype_from_typen(layer["__type"])
|
||||
if rtype is None:
|
||||
raise ValueError(f"{ConsoleFrontColor.RED}当前层不包含类型信息: {ConsoleFrontColor.RESET}{LimitStringLength(str(layer), 100)}")
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"layer: {ConsoleFrontColor.RESET}{LimitStringLength(str(layer), 100)}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, rtype: {ConsoleFrontColor.RESET}{rtype.ToString()}")
|
||||
|
||||
# 处理值类型
|
||||
if (rtype.IsValueType or
|
||||
rtype.Verify(Any) or
|
||||
(layer is None and rtype.Verify(type(None)))
|
||||
):
|
||||
return layer
|
||||
# 处理集合类型
|
||||
elif rtype.IsCollection:
|
||||
try:
|
||||
if rtype.IsList:
|
||||
element_type = rtype.GenericArgs[0] if len(rtype.GenericArgs) > 0 else Any
|
||||
return [ dfs(TypeManager.GetInstance().CreateOrGetRefType(element_type), iter_) for iter_ in layer ]
|
||||
elif rtype.IsSet:
|
||||
element_type = rtype.GenericArgs[0] if len(rtype.GenericArgs) > 0 else Any
|
||||
return { dfs(TypeManager.GetInstance().CreateOrGetRefType(element_type), iter_) for iter_ in layer }
|
||||
elif rtype.IsTuple:
|
||||
element_types: List[type] = rtype.GenericArgs
|
||||
result: tuple = tuple(None for _ in layer)
|
||||
if element_types is None or len(element_types) == 0:
|
||||
element_types = [Any] * len(layer)
|
||||
for index, iter_ in enumerate(layer):
|
||||
result[index] = dfs(TypeManager.GetInstance().CreateOrGetRefType(element_types[index]), iter_)
|
||||
return result
|
||||
elif rtype.IsDictionary:
|
||||
element_key, element_value = (rtype.GenericArgs[0], rtype.GenericArgs[1]) if len(rtype.GenericArgs) > 1 else (Any, Any)
|
||||
return {
|
||||
dfs(TypeManager.GetInstance().CreateOrGetRefType(element_key), keyname):
|
||||
dfs(TypeManager.GetInstance().CreateOrGetRefType(element_value), iter_)
|
||||
for keyname, iter_ in layer.items()
|
||||
}
|
||||
except Exception as e:
|
||||
raise ReflectionException(f"容器<{LimitStringLength(str(layer), 100)}>在反序列化时遇到错误:\n{e}") from e
|
||||
raise NotImplementedError(f"{ConsoleFrontColor.RED}不支持的容器: {LimitStringLength(str(layer), 100)}"\
|
||||
f"<{rtype.print_str(verbose=GetInternalEasySaveDebug())}>{ConsoleFrontColor.RESET}")
|
||||
# 处理对象类型
|
||||
elif isinstance(rtype.RealType, type) and hasattr(rtype.RealType, "__easy_deserialize__"):
|
||||
return rtype.RealType.__easy_deserialize__(layer)
|
||||
else:
|
||||
rinstance = rtype.CreateInstance()
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"rinstance rtype target: {ConsoleFrontColor.RESET}"\
|
||||
f"{rtype.print_str(verbose=True, flags=RefTypeFlag.Field|RefTypeFlag.Instance|RefTypeFlag.Public)}")
|
||||
fields:List[FieldInfo] = self._GetFields(rtype)
|
||||
for field in fields:
|
||||
if field.FieldName not in layer:
|
||||
continue
|
||||
field_rtype:RefType = None
|
||||
try:
|
||||
if field.FieldType == list and field.ValueType.IsGeneric:
|
||||
field_rtype = TypeManager.GetInstance().CreateOrGetRefType(ListIndictaor(field.ValueType.GenericArgs[0]))
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}List<"\
|
||||
f"{field_rtype.GenericArgs[0]}>")
|
||||
elif field.FieldType == set and field.ValueType.IsGeneric:
|
||||
field_rtype = TypeManager.GetInstance().CreateOrGetRefType(SetIndictaor(field.ValueType.GenericArgs[0]))
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}Set<"\
|
||||
f"{field_rtype.GenericArgs[0]}>")
|
||||
elif field.FieldType == tuple and field.ValueType.IsGeneric:
|
||||
field_rtype = TypeManager.GetInstance().CreateOrGetRefType(TupleIndictaor(field.ValueType.GenericArgs[0]))
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}Tuple<"\
|
||||
f"{field_rtype.GenericArgs[0]}>")
|
||||
elif field.FieldType == dict and field.ValueType.IsGeneric:
|
||||
field_rtype = TypeManager.GetInstance().CreateOrGetRefType(
|
||||
DictIndictaor(field.ValueType.GenericArgs[0], field.ValueType.GenericArgs[1])
|
||||
)
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}Dict<"\
|
||||
f"{field_rtype.GenericArgs[0]}, {field_rtype.GenericArgs[1]}>")
|
||||
else:
|
||||
field_rtype = TypeManager.GetInstance().CreateOrGetRefType(field.FieldType)
|
||||
if GetInternalEasySaveDebug():
|
||||
print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\
|
||||
f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}{field_rtype.RealType}"\
|
||||
f"<{field_rtype.GenericArgs}>")
|
||||
field.SetValue(rinstance, dfs(field_rtype, layer[field.FieldName]))
|
||||
except Exception as e:
|
||||
raise ReflectionException(f"Json字段{field.FieldName}={LimitStringLength(str(layer[field.FieldName]), 100)}: \n{e}") from e
|
||||
return rinstance
|
||||
|
||||
# 从根节点开始反序列化
|
||||
result_instance = dfs(rtype, layers)
|
||||
return result_instance
|
||||
|
||||
@sealed
|
||||
def _DoBinaryDeserialize(self, read_file:ToolFile, rtype:RefType) -> Any:
|
||||
'''
|
||||
反序列化: 二进制格式
|
||||
'''
|
||||
return read_file.load_as_binary()
|
||||
|
||||
@virtual
|
||||
def Deserialize(self, read_file:ToolFile, rtype:Optional[RefType]=None) -> Any:
|
||||
'''
|
||||
反序列化
|
||||
'''
|
||||
if self.setting.format == "json":
|
||||
return self._DoJsonDeserialize(read_file, rtype)
|
||||
elif self.setting.format == "binary":
|
||||
return self._DoBinaryDeserialize(read_file, rtype)
|
||||
else:
|
||||
raise NotImplementedError(f"不支持的格式: {self.setting.format}")
|
||||
|
||||
@virtual
|
||||
def Read[T](self, rtype:Optional[RTypen[T]]=None) -> T:
|
||||
'''
|
||||
读取数据
|
||||
'''
|
||||
read_file: ToolFile = ToolFile(self.setting.file)
|
||||
if not read_file.exists():
|
||||
raise FileNotFoundError(f"文件不存在: {read_file}")
|
||||
if read_file.is_dir():
|
||||
raise IsADirectoryError(f"文件是目录: {read_file}")
|
||||
return self.Deserialize(read_file, rtype)
|
||||
|
||||
class EasySave(any_class):
|
||||
@staticmethod
|
||||
def Write[T](rinstance:T, file:tool_file_or_str=None, *, setting:Optional[EasySaveSetting]=None) -> ToolFile:
|
||||
'''
|
||||
写入数据
|
||||
'''
|
||||
return ESWriter(setting=(setting if setting is not None else EasySaveSetting(file=UnwrapperFile2Str(file)))).Write(rinstance)
|
||||
|
||||
@overload
|
||||
@staticmethod
|
||||
def Read[T](
|
||||
rtype: Typen[T],
|
||||
file: tool_file_or_str = None,
|
||||
*,
|
||||
setting: Optional[EasySaveSetting] = None
|
||||
) -> T:
|
||||
...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Read[T](
|
||||
rtype: RTypen[T],
|
||||
file: tool_file_or_str = None,
|
||||
*,
|
||||
setting: Optional[EasySaveSetting] = None
|
||||
) -> T:
|
||||
...
|
||||
@staticmethod
|
||||
def Read[T](
|
||||
rtype: RTypen[T]|type,
|
||||
file: tool_file_or_str = None,
|
||||
*,
|
||||
setting: Optional[EasySaveSetting] = None
|
||||
) -> T:
|
||||
'''
|
||||
读取数据
|
||||
'''
|
||||
if isinstance(rtype, type):
|
||||
rtype = TypeManager.GetInstance().CreateOrGetRefType(rtype)
|
||||
return ESReader(setting=(setting if setting is not None else EasySaveSetting(file=UnwrapperFile2Str(file)))).Read(rtype)
|
1290
Convention/Runtime/File.py
Normal file
1290
Convention/Runtime/File.py
Normal file
File diff suppressed because it is too large
Load Diff
1638
Convention/Runtime/Reflection.py
Normal file
1638
Convention/Runtime/Reflection.py
Normal file
File diff suppressed because it is too large
Load Diff
59
Convention/Runtime/String.py
Normal file
59
Convention/Runtime/String.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from pathlib import Path
|
||||
from Config import *
|
||||
import re
|
||||
from pathlib import Path
|
||||
import xml.etree.ElementTree as ET
|
||||
from xml.dom import minidom
|
||||
import math
|
||||
|
||||
def LimitStringLength(data, max_length:int=50) -> str:
|
||||
s:str = data if data is str else str(data)
|
||||
if len(s) <= max_length:
|
||||
return s
|
||||
else:
|
||||
inside_str = "\n...\n...\n"
|
||||
# 计算头尾部分的长度
|
||||
head_length = max_length // 2
|
||||
tail_length = max_length - head_length - len(inside_str) # 3 是省略号的长度
|
||||
|
||||
# 截取头尾部分并连接
|
||||
return s[:head_length] + inside_str + s[-tail_length:]
|
||||
|
||||
def FillString(data:Any,
|
||||
max_length: int = 50,
|
||||
fill_char: str = " ",
|
||||
side: Literal["left", "right", "center"] = "right"
|
||||
) -> str:
|
||||
s:str = data if data is str else str(data)
|
||||
char = fill_char[0]
|
||||
if len(s) >= max_length:
|
||||
return s
|
||||
else:
|
||||
if side == "left":
|
||||
return s + char * (max_length - len(s))
|
||||
elif side == "right":
|
||||
return char * (max_length - len(s)) + s
|
||||
elif side == "center":
|
||||
left = (max_length - len(s)) // 2
|
||||
right = max_length - len(s) - left
|
||||
return char * left + s + char * right
|
||||
else:
|
||||
raise ValueError(f"Unsupported side: {side}")
|
||||
|
||||
def Bytes2Strings(lines:List[bytes], encoding='utf-8') -> List[str]:
|
||||
return [line.decode(encoding) for line in lines]
|
||||
|
||||
def Bytes2String(lines:List[bytes], encoding='utf-8') -> str:
|
||||
return "".join(Bytes2Strings(lines, encoding))
|
||||
|
||||
def word_segmentation(
|
||||
sentence: Union[str, light_str, Any],
|
||||
cut_all: bool = False,
|
||||
HMM: bool = True,
|
||||
use_paddle: bool = False
|
||||
) -> Sequence[Optional[Union[Any, str]]]:
|
||||
try:
|
||||
import jieba
|
||||
return jieba.dt.cut(UnWrapper(sentence), cut_all=cut_all, HMM=HMM, use_paddle=use_paddle)
|
||||
except ImportError:
|
||||
raise ValueError("jieba is not install")
|
11
[Test]/test.py
Normal file
11
[Test]/test.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from Convention.Runtime.Config import *
|
||||
|
||||
def run():
|
||||
print_colorful(ConsoleFrontColor.RED,"test")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
Reference in New Issue
Block a user