如何在Java中使用Python中的observer / observable工具编写程序? 我会在Java中写下类似的内容。
import java.util.Observable;
import java.util.Observer;
public class ObservDemo extends Object {
MyView view;
MyModel model;
public ObservDemo() {
view = new MyView();
model = new MyModel();
model.addObserver(view);
}
public static void main(String[] av) {
ObservDemo me = new ObservDemo();
me.demo();
}
public void demo() {
model.changeSomething();
}
/** The Observer normally maintains a view on the data */
class MyView implements Observer {
/** For now, we just print the fact that we got notified. */
public void update(Observable obs, Object x) {
System.out.println("update(" + obs + "," + x + ");");
}
}
/** The Observable normally maintains the data */
class MyModel extends Observable {
public void changeSomething() {
// Notify observers of change
setChanged();
notifyObservers();
}
}
}
(此代码取自以下链接 http://www.java2s.com/Code/Java/Design-Pattern/AsimpledemoofObservableandObserver.htm)
我如何用Python完成这样的事情?
答案 0 :(得分:5)
首先,正如Martijn Pieters所说,Python不是Java。 这意味着您可能不需要整个观察者/观察到的模式,但可以将其归结为更简化的版本。最后,我将展示更多pythonesque,但为了保持一个非常基本的java实现,你可以尝试这样的事情:
class Observer(object):
def notify(self,*args,**kwargs):
print args,kwargs
class Target(object):
def __init__(self,*observers):
self.observes = observers
#this notify for every access to the function
def event(self,data):
for obs in self.observes:
obs.notify('event',data)
print "event with",data
t = Target(Observer())
t.event(1)
#('event', 1) {}
#event with 1
否则你可以用装饰器来实现它,这非常相似:
def observe(f):
def decorated(self,*args,**kwargs):
for obs in self.observes:
obs.notify('event',*args,**kwargs)
return f(self,*args,**kwargs)
return decorated
class Target(object):
def __init__(self,*observers):
self.observes = observers
@observe
def otherevent(self,data):
print "other event with",data
现在,所有这些方法都有效,但它们并不是非常pythonic。想到以pythonic方式实现这样的事情的最好方法是实现一个包装器,它检查属性访问并调用回调函数(可以是观察者的通知函数,但它更通用的方法)
class Wrapper(object):
def __init__(self,wrapped,*callbacks):
self.wrapped = wrapped
self.callbacks = callbacks
def __getattr__(self,name):
res = self.wrapped.__getattribute__(name)
if not callable(res):
return res
def wrap(*args,**kwargs):
for c in self.callbacks:
c(self.wrapped,f,*args,**kwargs)
return res(*args,**kwargs)
return wrap
def __str__(self):
return self.wrapped.__str__()
#in this example I will keep a record of each call performed on a list
called = []
#this is the list
a = []
#and this is the wrapped list
w = Wrapper(a,lambda f,v,ign: called.append((f,v)) )
#I append an element to the wrapper
w.append(1)
#and I can see that it modify the original list
print a
#the print of the wrapped is well behaved, having defined the __str__ function
print w
#and we can see which function we called and which were the parameters
print called
这种方法更加复杂,因为你必须手动重定向所有魔术方法,但是更强大,因为允许将观察者模式实现到任何类型的对象,附加到任何兼容的函数,而不需要指定一般的观察类。有一些方法可以自动重定向所有魔术函数调用,但它有点复杂,只会混淆主要观点
在python中工作时忘记java的速度越快,它就越有趣。我建议你阅读这篇文章:
祝你工作顺利!