mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
425 lines
11 KiB
Python
425 lines
11 KiB
Python
from typing import Any
|
||
|
||
from zhenxun.services.log import logger
|
||
|
||
from .config import LOG_COMMAND
|
||
|
||
|
||
class CacheDict:
|
||
"""全局缓存字典类,提供类似普通字典的接口,但数据可以在内存中共享"""
|
||
|
||
def __init__(self, name: str, expire: int = 0):
|
||
"""初始化缓存字典
|
||
|
||
参数:
|
||
name: 字典名称
|
||
expire: 过期时间(秒),默认为0表示永不过期
|
||
"""
|
||
self.name = name.upper()
|
||
self.expire = expire
|
||
self._data = {}
|
||
# 自动尝试加载数据
|
||
self._try_load()
|
||
|
||
def _try_load(self):
|
||
"""尝试加载数据(非异步)"""
|
||
try:
|
||
# 延迟导入,避免循环引用
|
||
from zhenxun.services.cache import CacheRoot
|
||
|
||
# 检查是否已有缓存数据
|
||
if self.name in CacheRoot._data:
|
||
# 如果有,直接获取
|
||
data = CacheRoot._data[self.name]._data
|
||
if isinstance(data, dict):
|
||
self._data = data
|
||
except Exception:
|
||
# 忽略错误,使用空字典
|
||
pass
|
||
|
||
async def load(self) -> bool:
|
||
"""从缓存加载数据
|
||
|
||
返回:
|
||
bool: 是否成功加载
|
||
"""
|
||
try:
|
||
# 延迟导入,避免循环引用
|
||
from zhenxun.services.cache import CacheRoot
|
||
|
||
data = await CacheRoot.get_cache_data(self.name)
|
||
if isinstance(data, dict):
|
||
self._data = data
|
||
return True
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"加载缓存字典 {self.name} 失败", LOG_COMMAND, e=e)
|
||
return False
|
||
|
||
async def save(self) -> bool:
|
||
"""保存数据到缓存
|
||
|
||
返回:
|
||
bool: 是否成功保存
|
||
"""
|
||
try:
|
||
# 延迟导入,避免循环引用
|
||
from zhenxun.services.cache import CacheData, CacheRoot
|
||
|
||
# 检查缓存是否存在
|
||
if self.name not in CacheRoot._data:
|
||
# 创建缓存
|
||
async def get_func():
|
||
return self._data
|
||
|
||
CacheRoot._data[self.name] = CacheData(
|
||
name=self.name,
|
||
func=get_func,
|
||
expire=self.expire,
|
||
lazy_load=False,
|
||
cache=CacheRoot._cache,
|
||
)
|
||
# 直接设置数据,避免调用func
|
||
CacheRoot._data[self.name]._data = self._data
|
||
else:
|
||
# 直接更新数据
|
||
CacheRoot._data[self.name]._data = self._data
|
||
|
||
# 保存数据
|
||
await CacheRoot._data[self.name].set_data(self._data)
|
||
return True
|
||
except Exception as e:
|
||
logger.error(f"保存缓存字典 {self.name} 失败", LOG_COMMAND, e=e)
|
||
return False
|
||
|
||
def __getitem__(self, key: str) -> Any:
|
||
"""获取字典项
|
||
|
||
参数:
|
||
key: 字典键
|
||
|
||
返回:
|
||
Any: 字典值
|
||
"""
|
||
return self._data.get(key)
|
||
|
||
def __setitem__(self, key: str, value: Any) -> None:
|
||
"""设置字典项
|
||
|
||
参数:
|
||
key: 字典键
|
||
value: 字典值
|
||
"""
|
||
self._data[key] = value
|
||
|
||
def __delitem__(self, key: str) -> None:
|
||
"""删除字典项
|
||
|
||
参数:
|
||
key: 字典键
|
||
"""
|
||
if key in self._data:
|
||
del self._data[key]
|
||
|
||
def __contains__(self, key: str) -> bool:
|
||
"""检查键是否存在
|
||
|
||
参数:
|
||
key: 字典键
|
||
|
||
返回:
|
||
bool: 是否存在
|
||
"""
|
||
return key in self._data
|
||
|
||
def get(self, key: str, default: Any = None) -> Any:
|
||
"""获取字典项,如果不存在返回默认值
|
||
|
||
参数:
|
||
key: 字典键
|
||
default: 默认值
|
||
|
||
返回:
|
||
Any: 字典值或默认值
|
||
"""
|
||
return self._data.get(key, default)
|
||
|
||
def set(self, key: str, value: Any) -> None:
|
||
"""设置字典项
|
||
|
||
参数:
|
||
key: 字典键
|
||
value: 字典值
|
||
"""
|
||
self._data[key] = value
|
||
|
||
def pop(self, key: str, default: Any = None) -> Any:
|
||
"""删除并返回字典项
|
||
|
||
参数:
|
||
key: 字典键
|
||
default: 默认值
|
||
|
||
返回:
|
||
Any: 字典值或默认值
|
||
"""
|
||
return self._data.pop(key, default)
|
||
|
||
def clear(self) -> None:
|
||
"""清空字典"""
|
||
self._data.clear()
|
||
|
||
def keys(self) -> list[str]:
|
||
"""获取所有键
|
||
|
||
返回:
|
||
list[str]: 键列表
|
||
"""
|
||
return list(self._data.keys())
|
||
|
||
def values(self) -> list[Any]:
|
||
"""获取所有值
|
||
|
||
返回:
|
||
list[Any]: 值列表
|
||
"""
|
||
return list(self._data.values())
|
||
|
||
def items(self) -> list[tuple[str, Any]]:
|
||
"""获取所有键值对
|
||
|
||
返回:
|
||
list[tuple[str, Any]]: 键值对列表
|
||
"""
|
||
return list(self._data.items())
|
||
|
||
def __len__(self) -> int:
|
||
"""获取字典长度
|
||
|
||
返回:
|
||
int: 字典长度
|
||
"""
|
||
return len(self._data)
|
||
|
||
def __str__(self) -> str:
|
||
"""字符串表示
|
||
|
||
返回:
|
||
str: 字符串表示
|
||
"""
|
||
return f"CacheDict({self.name}, {len(self._data)} items)"
|
||
|
||
|
||
class CacheList:
|
||
"""全局缓存列表类,提供类似普通列表的接口,但数据可以在内存中共享"""
|
||
|
||
def __init__(self, name: str, expire: int = 0):
|
||
"""初始化缓存列表
|
||
|
||
参数:
|
||
name: 列表名称
|
||
expire: 过期时间(秒),默认为0表示永不过期
|
||
"""
|
||
self.name = name.upper()
|
||
self.expire = expire
|
||
self._data = []
|
||
# 自动尝试加载数据
|
||
self._try_load()
|
||
|
||
def _try_load(self):
|
||
"""尝试加载数据(非异步)"""
|
||
try:
|
||
# 延迟导入,避免循环引用
|
||
from zhenxun.services.cache import CacheRoot
|
||
|
||
# 检查是否已有缓存数据
|
||
if self.name in CacheRoot._data:
|
||
# 如果有,直接获取
|
||
data = CacheRoot._data[self.name]._data
|
||
if isinstance(data, list):
|
||
self._data = data
|
||
except Exception:
|
||
# 忽略错误,使用空列表
|
||
pass
|
||
|
||
async def load(self) -> bool:
|
||
"""从缓存加载数据
|
||
|
||
返回:
|
||
bool: 是否成功加载
|
||
"""
|
||
try:
|
||
# 延迟导入,避免循环引用
|
||
from zhenxun.services.cache import CacheRoot
|
||
|
||
data = await CacheRoot.get_cache_data(self.name)
|
||
if isinstance(data, list):
|
||
self._data = data
|
||
return True
|
||
return False
|
||
except Exception as e:
|
||
logger.error(f"加载缓存列表 {self.name} 失败", LOG_COMMAND, e=e)
|
||
return False
|
||
|
||
async def save(self) -> bool:
|
||
"""保存数据到缓存
|
||
|
||
返回:
|
||
bool: 是否成功保存
|
||
"""
|
||
try:
|
||
# 延迟导入,避免循环引用
|
||
from zhenxun.services.cache import CacheData, CacheRoot
|
||
|
||
# 检查缓存是否存在
|
||
if self.name not in CacheRoot._data:
|
||
# 创建缓存
|
||
async def get_func():
|
||
return self._data
|
||
|
||
CacheRoot._data[self.name] = CacheData(
|
||
name=self.name,
|
||
func=get_func,
|
||
expire=self.expire,
|
||
lazy_load=False,
|
||
cache=CacheRoot._cache,
|
||
)
|
||
# 直接设置数据,避免调用func
|
||
CacheRoot._data[self.name]._data = self._data
|
||
else:
|
||
# 直接更新数据
|
||
CacheRoot._data[self.name]._data = self._data
|
||
|
||
# 保存数据
|
||
await CacheRoot._data[self.name].set_data(self._data)
|
||
return True
|
||
except Exception as e:
|
||
logger.error(f"保存缓存列表 {self.name} 失败", LOG_COMMAND, e=e)
|
||
return False
|
||
|
||
def __getitem__(self, index: int) -> Any:
|
||
"""获取列表项
|
||
|
||
参数:
|
||
index: 列表索引
|
||
|
||
返回:
|
||
Any: 列表值
|
||
"""
|
||
if 0 <= index < len(self._data):
|
||
return self._data[index]
|
||
raise IndexError(f"列表索引 {index} 超出范围")
|
||
|
||
def __setitem__(self, index: int, value: Any) -> None:
|
||
"""设置列表项
|
||
|
||
参数:
|
||
index: 列表索引
|
||
value: 列表值
|
||
"""
|
||
# 确保索引有效
|
||
while len(self._data) <= index:
|
||
self._data.append(None)
|
||
self._data[index] = value
|
||
|
||
def __delitem__(self, index: int) -> None:
|
||
"""删除列表项
|
||
|
||
参数:
|
||
index: 列表索引
|
||
"""
|
||
if 0 <= index < len(self._data):
|
||
del self._data[index]
|
||
else:
|
||
raise IndexError(f"列表索引 {index} 超出范围")
|
||
|
||
def __len__(self) -> int:
|
||
"""获取列表长度
|
||
|
||
返回:
|
||
int: 列表长度
|
||
"""
|
||
return len(self._data)
|
||
|
||
def append(self, value: Any) -> None:
|
||
"""添加列表项
|
||
|
||
参数:
|
||
value: 列表值
|
||
"""
|
||
self._data.append(value)
|
||
|
||
def extend(self, values: list[Any]) -> None:
|
||
"""扩展列表
|
||
|
||
参数:
|
||
values: 要添加的值列表
|
||
"""
|
||
self._data.extend(values)
|
||
|
||
def insert(self, index: int, value: Any) -> None:
|
||
"""插入列表项
|
||
|
||
参数:
|
||
index: 插入位置
|
||
value: 列表值
|
||
"""
|
||
self._data.insert(index, value)
|
||
|
||
def pop(self, index: int = -1) -> Any:
|
||
"""删除并返回列表项
|
||
|
||
参数:
|
||
index: 列表索引,默认为最后一项
|
||
|
||
返回:
|
||
Any: 列表值
|
||
"""
|
||
return self._data.pop(index)
|
||
|
||
def remove(self, value: Any) -> None:
|
||
"""删除第一个匹配的列表项
|
||
|
||
参数:
|
||
value: 要删除的值
|
||
"""
|
||
self._data.remove(value)
|
||
|
||
def clear(self) -> None:
|
||
"""清空列表"""
|
||
self._data.clear()
|
||
|
||
def index(self, value: Any, start: int = 0, end: int | None = None) -> int:
|
||
"""查找值的索引
|
||
|
||
参数:
|
||
value: 要查找的值
|
||
start: 起始索引
|
||
end: 结束索引
|
||
|
||
返回:
|
||
int: 索引位置
|
||
"""
|
||
return self._data.index(
|
||
value, start, end if end is not None else len(self._data)
|
||
)
|
||
|
||
def count(self, value: Any) -> int:
|
||
"""计算值出现的次数
|
||
|
||
参数:
|
||
value: 要计数的值
|
||
|
||
返回:
|
||
int: 出现次数
|
||
"""
|
||
return self._data.count(value)
|
||
|
||
def __str__(self) -> str:
|
||
"""字符串表示
|
||
|
||
返回:
|
||
str: 字符串表示
|
||
"""
|
||
return f"CacheList({self.name}, {len(self._data)} items)"
|