在python中实现观察者模式的其他方法

2024-04-19 14:53:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在读一篇关于如何在python中实现观察者模式的文章post。在同一个帖子上也有这样的评论。在

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

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中并不是真正有用的,还有其他方法可以达到同样的效果。这是真的吗?如果能做到这一点呢?在

以下是观察者模式代码:

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')

Tags: toselfregisterifdef模式argsupdate
1条回答
网友
1楼 · 发布于 2024-04-19 14:53:58

在python中,有许多不同的方法可以“观察”某些东西。使用属性descriptors,自定义^{}decorators。。。在

下面是一个使用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)

然后您可以注册任何可调用的。在

^{pr2}$

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

这可能有助于了解引擎盖下的工作原理:

>>> 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方法作为装饰器,如下所示:

foo = Foo()

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

要使其工作,请记住register需要返回它注册的可调用文件。在

相关问题 更多 >