微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从导入的课程中“聆听” /装饰二传手

如何解决如何从导入的课程中“聆听” /装饰二传手

我不确定这是否是一种很好的使用方法,但是我对Python经验不足,所以请接受我的道歉。我已尝试对此进行一些研究,但其他相关问题已获得其他针对问题的解决方案-均不适用于我的具体情况。

我有一个处理我的特定机器学习模型的训练/查询的类。该算法在远程传感器上运行,如果未训练算法,则将各种值输入到对象中,该对象将返回None。训练后,它会根据分配给新输入的分类返回TrueFalse。有时,该类会更新几个阈值参数,我需要知道何时发生这种情况。

我正在使用套接字将消息从远程传感器传递到我的主服务器。我不想通过用消息传递代码填充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 举报,一经查实,本站将立刻删除。