feat: 改进对象系统

This commit is contained in:
2026-01-01 20:18:18 +08:00
parent 94839c6369
commit 9b32a01a10
39 changed files with 682 additions and 180 deletions

View File

@@ -0,0 +1,61 @@
# [调试] 将更改保存到文件
persist_to_file = 1
# [调试] 覆写时间, 设为 -1 以禁用
daystamp_override = -1
timestamp_override = -1
# [调试] 一键通过
quick_pass = 1
# 对于每个项目的默认新记忆原子数量
scheduled_num = 8
# UTC 时间戳修正 仅用于 UNIX 日时间戳的生成修正, 单位为秒
timezone_offset = +28800 # 中国标准时间 (UTC+8)
[interface]
[interface.memorizor]
autovoice = true # 自动语音播放, 仅限于 recognition 组件
[algorithm]
default = "SM-2" # 主要算法; 可选项: SM-2, SM-15M, FSRS
[puzzles] # 谜题默认配置
[puzzles.mcq]
max_riddles_num = 2
[puzzles.cloze]
min_denominator = 3
[paths] # 相对于配置文件的 ".." (即工作目录) 而言 或绝对路径
nucleon_dir = "./data/nucleon"
electron_dir = "./data/electron"
global_dir = "./data/global" # 全局数据路径, SM-15 等算法需要
orbital_dir = "./data/orbital"
cache_dir = "./data/cache"
template_dir = "./data/template"
[services] # 定义服务到提供者的映射
audio = "playsound" # 可选项: playsound(通用), termux(仅用于支持 Android Termux), mpg123(TODO)
tts = "edgetts" # 可选项: edgetts
llm = "openai" # 可选项: openai
sync = "webdav" # 可选项: 留空, webdav
[providers.tts.edgetts] # EdgeTTS 设置
voice = "zh-CN-XiaoxiaoNeural" # 可选项: zh-CN-YunjianNeural (男声), zh-CN-XiaoxiaoNeural (女声)
[providers.llm.openai] # 与 OpenAI 相容的语言模型接口服务设置
url = ""
key = ""
[providers.sync.webdav] # WebDAV 同步设置
url = ""
username = ""
password = ""
remote_path = "/heurams/"
verify_ssl = true
[sync]

View File

@@ -6,8 +6,8 @@ from heurams.services.logger import get_logger
from .screens.about import AboutScreen
from .screens.dashboard import DashboardScreen
from .screens.repocreator import NucleonCreatorScreen
from .screens.precache import PrecachingScreen
from .screens.repocreator import NucleonCreatorScreen
from .screens.synctool import SyncScreen
logger = get_logger(__name__)

View File

@@ -7,8 +7,8 @@ from heurams.services.logger import get_logger
from .screens.about import AboutScreen
from .screens.dashboard import DashboardScreen
from .screens.repocreator import NucleonCreatorScreen
from .screens.precache import PrecachingScreen
from .screens.repocreator import NucleonCreatorScreen
logger = get_logger(__name__)

View File

@@ -1,5 +1,5 @@
"""关于界面
"""
"""关于界面"""
from textual.app import ComposeResult
from textual.containers import ScrollableContainer
from textual.screen import Screen

View File

@@ -1,5 +1,5 @@
"""仪表盘界面
"""
"""仪表盘界面"""
import pathlib
from textual.app import ComposeResult
@@ -62,7 +62,8 @@ class DashboardScreen(Screen):
Returns:
dict: 包含显示文本的字典,键为行号
"""
from heurams.kernel.repository.particle_loader import load_electron, load_nucleon
from heurams.kernel.repository.particle_loader import (load_electron,
load_nucleon)
result = {}
filestem = pathlib.Path(filename).stem

View File

@@ -1,2 +1 @@
"""笔记界面
"""
"""笔记界面"""

View File

@@ -1,2 +1 @@
"""整体式记忆工作界面
"""
"""整体式记忆工作界面"""

View File

@@ -1,5 +1,5 @@
"""队列式记忆工作界面
"""
"""队列式记忆工作界面"""
from enum import Enum, auto
from textual.app import ComposeResult
@@ -8,8 +8,8 @@ from textual.reactive import reactive
from textual.screen import Screen
from textual.widgets import Button, Footer, Header, Label, Static
import heurams.kernel.particles as pt
import heurams.kernel.evaluators as pz
import heurams.kernel.particles as pt
from heurams.context import config_var
from heurams.kernel.reactor import *
from heurams.services.logger import get_logger

View File

@@ -1,5 +1,5 @@
"""缓存工具界面
"""
"""缓存工具界面"""
import pathlib
from textual.app import ComposeResult

View File

@@ -1,5 +1,5 @@
"""记忆准备界面
"""
"""记忆准备界面"""
from textual.app import ComposeResult
from textual.containers import ScrollableContainer
from textual.reactive import reactive

View File

@@ -1,2 +1 @@
""""前进电台" 界面
"""
""" "前进电台" 界面"""

View File

@@ -1,5 +1,5 @@
"""仓库创建向导界面
"""
"""仓库创建向导界面"""
from pathlib import Path
import toml

View File

@@ -1,5 +1,5 @@
"""同步工具界面
"""
"""同步工具界面"""
import pathlib
import time

View File

@@ -4,8 +4,8 @@ import random
from typing import TypedDict
import heurams.interface.widgets as pzw
import heurams.kernel.particles as pt
import heurams.kernel.evaluators as pz
import heurams.kernel.particles as pt
staging = {} # 细粒度缓存区, 是 ident -> quality 的封装

View File

@@ -7,8 +7,8 @@ from textual.message import Message
from textual.widget import Widget
from textual.widgets import Button, Label
import heurams.kernel.particles as pt
import heurams.kernel.evaluators as pz
import heurams.kernel.particles as pt
from heurams.services.logger import get_logger
from .base_puzzle_widget import BasePuzzleWidget

View File

@@ -5,8 +5,8 @@ from textual.containers import Container, ScrollableContainer
from textual.widget import Widget
from textual.widgets import Button, Label
import heurams.kernel.particles as pt
import heurams.kernel.evaluators as pz
import heurams.kernel.particles as pt
from heurams.services.hasher import hash
from heurams.services.logger import get_logger

View File

@@ -1,8 +1,8 @@
from heurams.services.logger import get_logger
from .base import BaseAlgorithm
from .sm2 import SM2Algorithm
from .sm15m import SM15MAlgorithm
from .base import BaseAlgorithm
logger = get_logger(__name__)

View File

@@ -75,4 +75,3 @@ class BaseAlgorithm:
return 1
except:
return 0

View File

@@ -6,6 +6,7 @@ from .base import BaseEvaluator
logger = get_logger(__name__)
class GuessEvaluator(BaseEvaluator):
def __init__(self):
super().__init__()
super().__init__()

View File

@@ -1,4 +1,4 @@
from .atom import Atom
from .electron import Electron
from .nucleon import Nucleon
from .orbital import Orbital
from .orbital import Orbital

View File

@@ -5,7 +5,6 @@ from typing import TypedDict
import toml
from heurams.context import config_var
from heurams.services.logger import get_logger
from .electron import Electron
@@ -19,11 +18,13 @@ class AtomRegister_runtime(TypedDict):
min_rate: int # 最低评分
new_activation: bool # 新激活
class AtomRegister(TypedDict):
nucleon: Nucleon
electron: Electron
runtime: AtomRegister_runtime
class Atom:
"""
统一处理一系列对象的所有信息与持久化:
@@ -39,10 +40,10 @@ class Atom:
"new_activation": False,
}
def __init__(self, nucleon_obj = None, electron_obj = None, orbital_obj = None):
self.ident = nucleon_obj["ident"] # type: ignore
def __init__(self, nucleon_obj=None, electron_obj=None, orbital_obj=None):
self.ident = nucleon_obj["ident"] # type: ignore
self.registry: AtomRegister = { # type: ignore
"ident": nucleon_obj["ident"], # type: ignore
"ident": nucleon_obj["ident"], # type: ignore
"nucleon": nucleon_obj,
"electron": electron_obj,
"orbital": orbital_obj,
@@ -53,7 +54,7 @@ class Atom:
self.registry["runtime"]["new_activation"] = True
def init_runtime(self):
self.registry['runtime'] = AtomRegister_runtime(**self.default_runtime)
self.registry["runtime"] = AtomRegister_runtime(**self.default_runtime)
def minimize(self, rating):
"""效果等同于 self.registry['runtime']['min_rate'] = min(rating, self.registry['runtime']['min_rate'])
@@ -97,4 +98,4 @@ class Atom:
def __setitem__(self, key, value):
if key == "ident":
raise AttributeError("应为只读")
self.registry[key] = value
self.registry[key] = value

View File

@@ -1,12 +1,14 @@
from copy import deepcopy
from typing import TypedDict
import heurams.kernel.algorithms as algolib
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
import heurams.kernel.algorithms as algolib
from copy import deepcopy
logger = get_logger(__name__)
class Electron:
"""电子: 单算法支持的记忆数据包装"""
@@ -89,11 +91,11 @@ class Electron:
def __len__(self):
"""仅返回当前算法的配置数量"""
return len(self.algodata[self.algo.algo_name])
@staticmethod
def create_on_electonic_data(electronic_data: tuple, algo_name: str = ""):
_data = electronic_data
ident = _data[0]
algodata = _data[1]
ident = ident
return Electron(ident, algodata, algo_name)
return Electron(ident, algodata, algo_name)

View File

@@ -1,17 +1,17 @@
from heurams.services.logger import get_logger
from copy import deepcopy
from heurams.services.logger import get_logger
from heurams.utils.evalizor import Evalizer
logger = get_logger(__name__)
class Nucleon:
"""原子核: 带有运行时隔离的模板化只读材料元数据容器
"""
"""原子核: 带有运行时隔离的模板化只读材料元数据容器"""
def __init__(self, ident, payload, common):
self.ident = ident
env = {
"payload": payload
}
env = {"payload": payload}
self.evalizer = Evalizer(environment=env)
self.data = self.evalizer(deepcopy((payload | common)))
@@ -19,10 +19,10 @@ class Nucleon:
if key == "ident":
return self.ident
return self.data[key]
def __setitem__(self, key, value):
raise AttributeError("应为只读")
def __delitem__(self, key):
raise AttributeError("应为只读")
@@ -31,12 +31,12 @@ class Nucleon:
def __contains__(self, key):
return key in (self.data)
def get(self, key, default=None):
if key in self:
return self[key]
return default
def __len__(self):
return len(self.data)
@@ -48,5 +48,5 @@ class Nucleon:
_data = nucleonic_data
payload = _data[1][0]
common = _data[1][1]
ident = _data[0] #TODO:实现eval
return Nucleon(ident, payload, common)
ident = _data[0] # TODO:实现eval
return Nucleon(ident, payload, common)

View File

@@ -1,14 +1,16 @@
from heurams.utils.lict import Lict
from heurams.utils.evalizor import Evalizer
from heurams.utils.lict import Lict
class Orbital():
class Orbital:
@classmethod
def create_orbital(cls, schedule: list, phase_def: dict):
phase_def = Lict(initdict=phase_def) # type: ignore
phase_def = Lict(initdict=phase_def) # type: ignore
orbital = Lict()
for i in schedule:
orbital[i] = Lict(phase_def[i])
return orbital
@classmethod
def create_orbital_on_orbitic_data(cls, orbitic_data):
return cls.create_orbital(orbitic_data["schedule"], orbitic_data["phases"])
return cls.create_orbital(orbitic_data["schedule"], orbitic_data["phases"])

View File

@@ -1,7 +1,7 @@
import random
import heurams.kernel.particles as pt
import heurams.kernel.evaluators as puz
import heurams.kernel.particles as pt
from heurams.services.logger import get_logger
from .states import PhaserState

View File

@@ -1,5 +1,5 @@
from ...utils.lict import Lict
def merge(x: Lict, y: Lict):
return Lict(list(x.values()) + list(y.values()))

View File

@@ -1,3 +1,3 @@
class Navi():
class Navi:
def __init__(self, init) -> None:
pass
pass

View File

@@ -1,11 +1,15 @@
import json
from functools import reduce
from pathlib import Path
import heurams.kernel.particles as pt
import toml
import json
import heurams.kernel.particles as pt
from ...utils.lict import Lict
class Repo():
class Repo:
file_mapping = {
"schedule": "schedule.toml",
"payload": "payload.toml",
@@ -24,13 +28,21 @@ class Repo():
default_save_list = ["algodata"]
def __init__(self, schedule: dict, payload: Lict, manifest: dict, typedef: dict, algodata: Lict, source = None) -> None:
def __init__(
self,
schedule: dict,
payload: Lict,
manifest: dict,
typedef: dict,
algodata: Lict,
source=None,
) -> None:
self.schedule: dict = schedule
self.manifest: dict = manifest
self.typedef: dict = typedef
self.payload: Lict = payload
self.algodata: Lict = algodata
self.source: Path | None = source # 若存在, 指向 repo 所在 dir
self.source: Path | None = source # 若存在, 指向 repo 所在 dir
self.database = {
"schedule": self.schedule,
"payload": self.payload,
@@ -42,35 +54,43 @@ class Repo():
self.generate_particles_data()
def generate_particles_data(self):
self.nucleonic_data_lict = Lict(initlist=list(map(self._attach(self.typedef), self.payload)))
self.nucleonic_data_lict = Lict(
initlist=list(map(
self._nucleonic_proc,
self.payload))
)
self.electronic_data_lict = self.algodata
self.orbitic_data = self.schedule
@staticmethod
def _attach(value):
def inner(x):
return (x, value)
return inner
def _nucleonic_proc(self, unit):
ident = unit[0]
common = self.typedef["common"]
return (ident, (unit[1], common))
@staticmethod
def _merge(value):
def inner(x):
return map(x, value)
return (x, value)
return inner
def __len__(self):
return len(self.payload)
def persist_to_repodir(self, save_list: list | None = None, source: Path | None= None):
def persist_to_repodir(
self, save_list: list | None = None, source: Path | None = None
):
if save_list == None:
save_list = self.default_save_list
if self.source != None and source == None:
source = self.source
if source == None:
raise FileNotFoundError("不存在仓库到文件的映射")
source.mkdir(parents=True, exist_ok=False)
for keyname in save_list:
filename = self.file_mapping[keyname]
with open(source / filename, 'w') as f:
with open(source / filename, "w") as f:
try:
dict_data = self.database[keyname].dicted_data
except:
@@ -81,22 +101,22 @@ class Repo():
json.dump(dict_data, f)
else:
raise ValueError(f"不支持的文件类型: {filename}")
def export_to_single_dict(self):
return self.database
@classmethod
def create_new_repo(cls, source = None):
def create_new_repo(cls, source=None):
default_database = {
"schedule": {},
"payload": Lict([]),
"algodata": Lict([]),
"manifest": {},
"typedef": {},
"source": source
"source": source,
}
return Repo(**default_database)
@classmethod
def create_from_repodir(cls, source: Path):
database = {}
@@ -117,17 +137,17 @@ class Repo():
raise ValueError(f"不支持的数据容器: {cls.type_mapping[keyname]}")
database["source"] = source
return Repo(**database)
@classmethod
def create_from_single_dict(cls, dictdata, source: Path | None = None):
database = dictdata
database["source"] = source
return Repo(**database)
@classmethod
def check_repodir(cls, source: Path):
try:
cls.create_from_repodir(source)
return 1
except:
return 0
return 0

View File

@@ -1,18 +1,19 @@
class Evalizer():
class Evalizer:
"""几乎无副作用的模板系统
接受环境信息并创建一个模板解析工具, 工具传入参数支持list, dict及其嵌套
接受环境信息并创建一个模板解析工具, 工具传入参数支持list, dict及其嵌套
副作用问题: 仅存在于 eval 函数
"""
# TODO: 弃用风险极高的 eval
# 理论上已经限制了全局函数 但eval仍有风险
# TODO: 异步/多线程执行避免堵塞
def __init__(self, environment: dict) -> None:
self.env = environment
def __call__(self, anyobj):
return self.travel(anyobj)
def travel(self, anyobj):
if isinstance(anyobj, list):
return list(map(self.travel, anyobj))
@@ -30,4 +31,4 @@ class Evalizer():
ret = eval(s, {}, self.env)
if not isinstance(ret, str):
ret = str(ret)
return ret
return ret

View File

@@ -1,23 +1,29 @@
from collections import UserList
from typing import Any, Iterator
class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
""""列典" 对象
同时兼容字典和列表大多数 API, 两边数据同步的容器
列表数据是 dictobj.items() 的格式
class Lict(UserList): # TODO: 优化同步(惰性同步), 当前性能为 O(n)
""" "列典" 对象
同时兼容字典和列表大多数 API, 两边数据同步的容器
列表数据是 dictobj.items() 的格式
支持根据字典或列表初始化
限制要求:
- 键名一定唯一, 且仅能为字符串
- 值一定是引用对象
- 不使用并发
- 不在乎列表顺序语义(严格按键名字符序排列)和列表索引查找, 因此外部的 sort, index 等功能不可用
- append 的元组中, 表示键名的元素不能重复, 否则会导致覆盖行为
- append 的元组中, 表示键名的元素不能重复, 否则会导致覆盖行为
只有在 Python 3.7+ 中, forced_order 行为才能被取消.
"""
def __init__(self, initlist: list | None = None, initdict: dict | None = None, forced_order = True):
def __init__(
self,
initlist: list | None = None,
initdict: dict | None = None,
forced_order=True,
):
self.dicted_data = {}
if initdict != None:
initlist = list(initdict.items())
@@ -26,7 +32,7 @@ class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
self._sync_based_on_list()
if self.forced_order:
self.data.sort()
def _sync_based_on_dict(self):
self.data = list(self.dicted_data.items())
if self.forced_order:
@@ -45,7 +51,7 @@ class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
return self.dicted_data[i]
else:
return super().__getitem__(i)
def __setitem__(self, i, item):
if isinstance(i, str):
self.dicted_data[i] = item
@@ -55,7 +61,7 @@ class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
raise NotImplementedError
super().__setitem__(i, item)
self._sync_based_on_list()
def __delitem__(self, i):
if isinstance(i, str):
del self.dicted_data[i]
@@ -65,25 +71,29 @@ class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
self._sync_based_on_list()
def __contains__(self, item):
return (item in self.data or item in self.keys() or item in self.values())
return item in self.data or item in self.keys() or item in self.values()
def append(self, item: Any) -> None:
if item != (item[0], item[1]):
raise NotImplementedError
super().append(item)
self._sync_based_on_list()
if self.forced_order:
self.data.sort()
def insert(self, i: int, item: Any) -> None:
if item != (item[0], item[1]): # 确保 item 是遵从限制的元组
if item != (item[0], item[1]): # 确保 item 是遵从限制的元组
raise NotImplementedError
super().insert(i, item)
self._sync_based_on_list()
if self.forced_order:
self.data.sort()
def pop(self, i: int = -1) -> Any:
res = super().pop(i)
self._sync_based_on_list()
return res
def remove(self, item: Any) -> None:
if isinstance(item, str):
item = (item, self.dicted_data[item])
@@ -91,29 +101,31 @@ class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
raise NotImplementedError
super().remove(item)
self._sync_based_on_list()
if self.forced_order:
self.data.sort()
def clear(self) -> None:
super().clear()
self._sync_based_on_list()
def index(self):
raise NotImplementedError
def extend(self):
raise NotImplementedError
def sort(self):
raise NotImplementedError
def reverse(self):
raise NotImplementedError
def keys(self):
return self.dicted_data.keys()
def values(self):
return self.dicted_data.values()
def items(self):
return self.data
@@ -122,4 +134,4 @@ class Lict(UserList): #TODO: 优化同步(惰性同步), 当前性能为 O(n)
@classmethod
def key_equality(cls, a, b):
return a.keys() == b.keys()
return a.keys() == b.keys()

View File

@@ -1,241 +1,241 @@
class RefVar:
def __init__(self, initvalue) -> None:
self.data = initvalue
def __repr__(self) -> str:
return f"RefVar({repr(self.data)})"
def __str__(self) -> str:
return str(self.data)
def __add__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data + other.data)
return RefVar(self.data + other)
def __radd__(self, other):
return RefVar(other + self.data)
def __sub__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data - other.data)
return RefVar(self.data - other)
def __rsub__(self, other):
return RefVar(other - self.data)
def __mul__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data * other.data)
return RefVar(self.data * other)
def __rmul__(self, other):
return RefVar(other * self.data)
def __truediv__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data / other.data)
return RefVar(self.data / other)
def __rtruediv__(self, other):
return RefVar(other / self.data)
def __floordiv__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data // other.data)
return RefVar(self.data // other)
def __rfloordiv__(self, other):
return RefVar(other // self.data)
def __mod__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data % other.data)
return RefVar(self.data % other)
def __rmod__(self, other):
return RefVar(other % self.data)
def __pow__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data ** other.data)
return RefVar(self.data ** other)
return RefVar(self.data**other.data)
return RefVar(self.data**other)
def __rpow__(self, other):
return RefVar(other ** self.data)
return RefVar(other**self.data)
def __neg__(self):
return RefVar(-self.data)
def __pos__(self):
return RefVar(+self.data)
def __abs__(self):
return RefVar(abs(self.data))
def __eq__(self, other):
if isinstance(other, RefVar):
return self.data == other.data
return self.data == other
def __ne__(self, other):
return not self.__eq__(other)
def __lt__(self, other):
if isinstance(other, RefVar):
return self.data < other.data
return self.data < other
def __le__(self, other):
if isinstance(other, RefVar):
return self.data <= other.data
return self.data <= other
def __gt__(self, other):
if isinstance(other, RefVar):
return self.data > other.data
return self.data > other
def __ge__(self, other):
if isinstance(other, RefVar):
return self.data >= other.data
return self.data >= other
# 位运算
def __and__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data & other.data)
return RefVar(self.data & other)
def __rand__(self, other):
return RefVar(other & self.data)
def __or__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data | other.data)
return RefVar(self.data | other)
def __ror__(self, other):
return RefVar(other | self.data)
def __xor__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data ^ other.data)
return RefVar(self.data ^ other)
def __rxor__(self, other):
return RefVar(other ^ self.data)
def __lshift__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data << other.data)
return RefVar(self.data << other)
def __rlshift__(self, other):
return RefVar(other << self.data)
def __rshift__(self, other):
if isinstance(other, RefVar):
return RefVar(self.data >> other.data)
return RefVar(self.data >> other)
def __rrshift__(self, other):
return RefVar(other >> self.data)
def __invert__(self):
return RefVar(~self.data)
# 类型转换
def __int__(self):
return int(self.data)
def __float__(self):
return float(self.data)
def __bool__(self):
return bool(self.data)
def __complex__(self):
return complex(self.data)
def __bytes__(self):
return bytes(self.data)
def __hash__(self):
return hash(self.data)
# 容器操作(如果底层数据支持)
def __len__(self):
return len(self.data)
def __getitem__(self, key):
return self.data[key]
def __setitem__(self, key, value):
self.data[key] = value
def __delitem__(self, key):
del self.data[key]
def __contains__(self, item):
return item in self.data
def __iter__(self):
return iter(self.data)
def __iadd__(self, other):
if isinstance(other, RefVar):
self.data += other.data
else:
self.data += other
return self
def __isub__(self, other):
if isinstance(other, RefVar):
self.data -= other.data
else:
self.data -= other
return self
def __imul__(self, other):
if isinstance(other, RefVar):
self.data *= other.data
else:
self.data *= other
return self
def __itruediv__(self, other):
if isinstance(other, RefVar):
self.data /= other.data
else:
self.data /= other
return self
def __ifloordiv__(self, other):
if isinstance(other, RefVar):
self.data //= other.data
else:
self.data //= other
return self
def __imod__(self, other):
if isinstance(other, RefVar):
self.data %= other.data
else:
self.data %= other
return self
def __ipow__(self, other):
if isinstance(other, RefVar):
self.data **= other.data
else:
self.data **= other
return self
def __call__(self, *args, **kwargs):
if callable(self.data):
return self.data(*args, **kwargs)
raise TypeError(f"'{type(self.data).__name__}' object is not callable")
def __getattr__(self, name):
return getattr(self.data, name)
return getattr(self.data, name)