python - 我将如何“听”/装饰导入类中的设置器
问题描述
我不确定这是否是一种很好的使用方法,但我对 Python 的经验并不丰富,所以请接受我的道歉。我试图对此进行一些研究,但其他相关问题已经给出了替代的特定问题的解决方案——这些都不适用于我的具体案例。
我有一门课来处理我的特定机器学习模型的训练/查询。None
该算法在远程传感器上运行,如果算法未经过训练,则将各种值输入返回的对象中。训练后,它会根据分配给新输入的分类返回True
或返回。False
有时,该类会更新几个阈值参数,我需要知道何时发生这种情况。
我正在使用套接字将消息从远程传感器传递到我的主服务器。我不想通过填充消息传递代码来使 ML 算法类复杂化,因此我一直在Main
导入“算法”类的类中处理这个问题。我希望Main
该类能够确定阈值参数何时更新并将其报告回服务器。
class MyAlgorithmClass:
def feed_value(self):
....
class Main:
def __init__(self):
self._algorithm_data = MyAlgorithmClass()
self._sensor_data_queue = Queue()
def process_data(self):
while True:
sensor_value = self._sensor_data_queue.get()
result, value = self._algorithm_data.feed_value(sensor_value)
if result is None:
# value represents % training complete
self._socket.emit('training', value)
elif result is True:
# value represents % chance that input is categoryA
self._socket.emit('categoryA', value)
elif result is False:
...
我最初的想法是MyAlgorithmClass
使用 setter 添加一个属性。然后我可以在我的班级中装饰它,Main
以便每次调用 setter 时,我都可以使用该值......例如:
class MyAlgorithmClass:
@property
def param1(self):
return self._param1
@param1.setter
def param1(self, value):
self._param1 = value
class Main:
def __init__(self):
self._algorithm_data = MyAlgorithmClass()
self._sensor_data_queue = Queue()
def watch_param1(func):
def inner(*args):
self._socket.emit('param1_updated', *args)
func(*args)
我现在的问题是如何self._algorithm_data.param1
用 装饰二传手watch_param1
?如果我只是简单地设置self._algorithm_data.param1 = watch_param1
,那么我最终将设置self._algorithm_data._param1
等于我的功能,这不是我想要做的。
我可以使用 getter/setter 方法而不是属性,但这不是很pythonic,并且由于多人正在修改此代码,我不希望稍后其他人为属性替换/更改这些方法。
这里最好的方法是什么?这是一个小例子,但稍后我会有稍微复杂一点的例子,我不想要会导致算法类过于复杂的东西。显然,另一种选择是观察者模式,但我不确定在某些情况下我只有一个变量要监控的地方有多合适。
我真的很难找到一个好的解决方案,所以任何建议都将不胜感激。
提前致谢,
汤姆
解决方案
使用描述符。它们允许您在 Python 中自定义属性查找、存储和删除。
带有描述符的代码的简化玩具版本如下所示:
class WatchedParam:
def __init__(self, name):
self.name = name
def __get__(self, instance, insttype=None):
print(f"{self.name} : value accessed")
return getattr(instance, '_' + self.name)
def __set__(self, instance, new_val):
print(f"{self.name} : value set")
setattr(instance, '_' + self.name, new_val)
class MyAlgorithmClass:
param1 = WatchedParam("param1")
param2 = WatchedParam("param2")
def __init__(self, param1, param2, param3):
self.param1 = param1
self.param2 = param2
self.param3 = param3
class Main:
def __init__(self):
self._data = MyAlgorithmClass(10, 20, 50)
m = Main()
m._data.param1 # calls WatchedParam.__get__
m._data.param2 = 100 # calls WatchedParam.__set__
该类WatchedParam
是一个描述符,可用于MyAlgorithmClass
指定需要监控的参数。
推荐阅读
- javascript - 多个数组,复选框
- sql - KDB 的 Case When 语句
- javascript - TypeError: undefined is not an object (evalating 'ctx.item.Street') (NativeScript)
- javascript - 将平面结构转换为按属性排序的分层结构
- c# - 如何更新多个表中的单个记录?
- sql - 对于第 1 列中的每个值,根据第 2 列中的最大值获取第 3 列的值
- r - 如何对数值向量中的值进行分组和汇总
- javascript - 如何将复选框开关中的值发送到 MySQL 数据库
- javascript - 如何删除不包含任何字符串的行?角
- git - 如何将本地和远程 git 存储库恢复到以前的提交?