如何在值变化时触发函数?
我意识到这个问题和事件处理有关,我也读过关于Python事件处理器和调度器的内容,所以要么没有回答我的问题,要么我完全没理解其中的信息。
我想让对象 A
的方法 m()
在值 v
变化时被触发:
比如说(假设钱能让人快乐):
global_wealth = 0
class Person()
def __init__(self):
self.wealth = 0
global global_wealth
# here is where attribute should be
# bound to changes in 'global_wealth'
self.happiness = bind_to(global_wealth, how_happy)
def how_happy(self, global_wealth):
return self.wealth / global_wealth
所以每当 global_wealth
的值发生变化时,所有 Person
类的实例都应该相应地改变它们的 happiness
值。
注意:我不得不编辑这个问题,因为最初的版本似乎暗示我需要 getter 和 setter 方法。抱歉让人困惑。
6 个回答
你所寻找的东西叫做(函数式)响应式编程。在Common Lisp中有一个叫做Cells的项目,具体可以查看Cells项目和Cells宣言;而在Python中,有Trellis库。
电子表格也使用了相同的思路。这种方法非常适合跟踪多个相互关联的参数,比如在图形用户界面编程中。
响应式编程和观察者模式有点相似,但有一个重要的区别:
与观察者模式的相似之处 不过,把数据流的概念整合进编程语言中,会让表达这些概念变得更简单,因此可以增加数据流图的细节。例如,观察者模式通常描述的是整个对象或类之间的数据流,而面向对象的响应式编程可以针对对象或类的成员。
如果你想在属性改变时执行一些代码,可以使用属性。不过要注意,当属性改变时,如果引起了很大的副作用或者消耗了很多资源,这可能会让使用你这个接口的人感到意外。因此在某些情况下,你可能更想用方法来代替属性。
class A(object):
def m(self, p_value):
print p_value
@property
def p(self):
return self._p
@p.setter
def p(self, value):
self._p = value
self.m(value)
你需要使用观察者模式。在下面的代码中,一个人订阅了全球财富实体的更新。当全球财富发生变化时,这个实体会通知所有的订阅者(观察者),告诉他们发生了变化。然后,这个人会根据这些变化进行更新。
在这个例子中,我使用了属性,但其实它们并不是必须的。有一点小提醒:属性只适用于新风格的类,所以在类声明后加上(object)是必须的,这样才能正常工作。
class GlobalWealth(object):
def __init__(self):
self._global_wealth = 10.0
self._observers = []
@property
def global_wealth(self):
return self._global_wealth
@global_wealth.setter
def global_wealth(self, value):
self._global_wealth = value
for callback in self._observers:
print('announcing change')
callback(self._global_wealth)
def bind_to(self, callback):
print('bound')
self._observers.append(callback)
class Person(object):
def __init__(self, data):
self.wealth = 1.0
self.data = data
self.data.bind_to(self.update_how_happy)
self.happiness = self.wealth / self.data.global_wealth
def update_how_happy(self, global_wealth):
self.happiness = self.wealth / global_wealth
if __name__ == '__main__':
data = GlobalWealth()
p = Person(data)
print(p.happiness)
data.global_wealth = 1.0
print(p.happiness)