Warm tip: This article is reproduced from serverfault.com, please click

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

(python - How would I 'listen' to/decorate a setter from an imported class)

发布于 2020-11-06 16:33:43

我不确定这是否是一种很好的使用方法,但是我对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使用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方法而不是属性,但这不是Python语言,而且由于许多人都在修改此代码,因此我不希望稍后再由其他人将这些方法替换/更改为属性。

最好的方法是什么?这是一个很小的示例,但是稍后我将提供稍微更复杂的示例,并且我不希望出现会导致算法类过于复杂的事情。显然,另一种选择是观察者模式,但是我不确定在这里在某些情况下只有一个变量要监视的情况是否合适。

我真的很难获得一个好的解决方案,因此任何建议将不胜感激。

提前致谢,

汤姆

Questioner
Tom Bailey
Viewed
11
Tom Bailey 2020-11-30 23:20:56

我寻求的解决方案如下,使用覆盖属性的“代理”子类。最终,一旦我对监视的参数有了更好的了解,就不再需要监视它们了。在这一点上,我将可以将代理替换为基类,并继续照常使用代码。

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)