Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的观察者可观察类_Python - Fatal编程技术网

python中的观察者可观察类

python中的观察者可观察类,python,Python,如何用Python和Java编写一个具有观察者/可观察设施的程序? 我会用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 MyMo

如何用Python和Java编写一个具有观察者/可观察设施的程序? 我会用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();
    }
  }
}
(此代码取自以下链接。) )


我如何在Python中完成这样的事情?

首先,正如Martijn Pieters所说,Python不是Java。 这意味着您可能不需要整个观察者/观察者模式,但可以将其归结为更简化的版本。最后,我将展示一些更具pythonnesque的东西,但为了保持非常基本的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
现在,所有这些方法都是有效的,但它们不是很像python。以pythonic的方式实现这样的东西的最好方法是实现一个检查属性访问并调用回调函数的包装器(可以是观察者的notify函数,但这是一种更通用的方法)

这种方法有点复杂,因为您必须手动重定向所有神奇的方法,但功能更强大,因为它允许将观察者模式实现到任何类型的对象,附加到任何兼容的函数,而无需指定观察者的通用类。有很多方法可以自动重定向所有神奇的函数调用,但这有点复杂,只会混淆要点

在使用python时,您忘记java的速度越快,它就会越有趣。我建议你读这篇文章:


祝你工作顺利

Python不是Java(幸运的是)。标准库中没有事件发布者/订阅者库,但是有很多方法可以在没有库的情况下实现这一点。太多了,事实上,你想实现什么?我想写一个程序,它同时充当服务器(比如说服务器a)和客户机。首先,客户端向外部服务器(比如服务器B)发送一些消息。然后该服务器向我们自己的服务器广播消息。我的服务器(A)应该根据它从服务器B得到的回复来操作我的客户机。在这种情况下,我需要让我的服务器可以观察到,让我的客户机可以观察到。我的客户机根据服务器中变量中的一些值进行操作。因此,当my server中的值发生更改时,应该立即通知它。我怎样才能实现这样的功能呢?我不知道第三条路有什么比这更像蟒蛇。当您需要观察者模式时,您可能会有一个比列表更大的体系结构,并且希望精确地控制何时以及如何通知观察者。在这方面,前两种解决方案更好地阅读、使用和维护imo。
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