如何解决如何从导入的课程中“聆听” /装饰二传手
我不确定这是否是一种很好的使用方法,但是我对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
。然后,可以在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,而且由于许多人都在修改此代码,所以我不希望稍后其他人将方法替换/更改为属性。
这里最好的方法是什么?这是一个很小的示例,但是稍后我将提供稍微更复杂的示例,并且我不希望出现会导致算法类过于复杂的事情。显然,另一种选择是“观察者”模式,但是我不确定在这里在某些情况下只监视一个变量的情况是否合适。
预先感谢
汤姆
解决方法
使用descriptors。他们允许您使用Python customize attribute lookup,storage,and deletion。
带有描述符的代码的简化玩具版本类似于:
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,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
中使用以指定需要监视的参数。
我寻求的解决方案如下,使用覆盖属性的“代理”子类。最终,一旦我对监视的参数有了更好的了解,就不再需要监视它们了。此时,我将可以将代理替换为基类,并继续照常使用代码。
class MyAlgorithmClassProxy(MyAlgorithmClass):
@property
def watch_param1(self):
return MyAlgorithmClass.watch_param1.fget(self)
@watch_param1.setter
def watch_param1(self,value):
self._socket.emit('param1_updated',*args)
MyAlgorithmClass.watch_param1.fset(self,value)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。