在python中实现观察者模式的替代方法 [英] alternate ways to implement observer pattern in python

查看:134
本文介绍了在python中实现观察者模式的替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看有关如何实现观察者模式的帖子帖子在python中.在同一帖子上有这些评论.

i was going through a post post about how observer pattern can be implemented in python . on the same post there are these comments.

1)在python中,您也可以只使用简单的函数,即观察者" 确实不需要上课.

1) In python you may as well just use plain functions, the ‘Observer’ class isnt really needed.

2)这是Java程序员一次尝试做的很好的例子 他们改用Python –觉得Python缺少了所有这些废话 并尝试移植"它.

2) This is great example of what Java programmers are trying to do once they switch to Python – they feel like Python is missing all that crap and try to "port" it.

这些注释暗示观察者模式在python中并没有真正的用处,并且还有其他方法可以达到相同的效果.那是真的吗,怎么办呢?

These comments imply that the observer pattern is not really useful in python and there exists other ways to achieve the same effect. is that true and if how can that be done?

这是观察者模式的代码:

Here is the code of observer pattern:

class Observable(object):

    def __init__(self):
        self.observers = []

    def register(self, observer):
        if not observer in self.observers:
            self.observers.append(observer)

    def unregister(self, observer):
        if observer in self.observers:
            self.observers.remove(observer)

    def unregister_all(self):
        if self.observers:
            del self.observers[:]

    def update_observers(self, *args, **kwargs):
        for observer in self.observers:
            observer.update(*args, **kwargs)

from abc import ABCMeta, abstractmethod

class Observer(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def update(self, *args, **kwargs):
        pass

class AmericanStockMarket(Observer):
    def update(self, *args, **kwargs):
        print("American stock market received: {0}\n{1}".format(args, kwargs))

class EuropeanStockMarket(Observer):
    def update(self, *args, **kwargs):
        print("European stock market received: {0}\n{1}".format(args, kwargs))


if __name__ == "__main__":
    observable = Observable()

    american_observer = AmericanStockMarket()
    observable.register(american_observer)

    european_observer = EuropeanStockMarket()
    observable.register(european_observer)

    observable.update_observers('Market Rally', something='Hello World')

推荐答案

您可以通过多种不同的方式观察" python中的内容.使用属性描述符,自定义装饰器 ...

There are many different ways you can "observe" something in python. Use property descriptors, custom __setattr__, decorators...

这是一个使用一流函数的简单示例:

Here is a simple example that uses first class functions:

class Foo(object):
    def __init__(self):
        self.observers = []

    def register(self, fn):
        self.observers.append(fn)
        return fn   # <-- See comments below answer

    def notify_observers(self, *args, **kwargs):
        for fn in self.observers:
            fn(*args, **kwargs)

然后您可以注册任何可呼叫对象.

You can then register any callable.

class Bar(object):
    def do_something(self, *args, **kwargs):
        pass # do something

foo = Foo()
bar = Bar()
foo.register(bar.do_something)

这将正常工作.对do_something的调用将具有正确的self值.因为对象的方法是可调用对象,它们带有对绑定到实例的引用.

This will work properly. The call to do_something will have the correct self value. Because an object's methods are callable objects which carry a reference to the instance they are bound to.

这可能有助于了解其幕后工作原理:

This might help understanding how it works under the hood:

>>> bar
<Bar object at 0x7f3fec4a5a58>
>>> bar.do_something
<bound method Bar.do_something of <Bar object at 0x7f3fec4a5a58>>
>>> type(bar.do_something)
<class 'method'>
>>> bar.do_something.__self__
<Bar object at 0x7f3fec4a5a58>


您还可以使用上面定义的register方法作为装饰器,如下所示:

You may also use the register method we defined above as a decorator, like this:

foo = Foo()

@foo.register
def do_something(*args, **kwargs):
    pass # do something

要执行此操作,只需记住register需要返回其已注册的可调用项.

For this to work, just remember that register needs to return the callable it registered.

这篇关于在python中实现观察者模式的替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆