gpt4 book ai didi

python - 在 python 中实现观察者模式的替代方法

转载 作者:太空狗 更新时间:2023-10-30 02:26:32 25 4
gpt4 key购买 nike

我正在浏览一个帖子 post关于如何在 python 中实现观察者模式。在同一个帖子上有这些评论。

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

最佳答案

在 python 中有许多不同的方法可以“观察”某些东西。使用属性 descriptors , 定制 __setattr__ , 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)

然后您可以注册任何可调用对象。

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

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

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

这可能有助于理解它在幕后是如何工作的:

>>> 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 需要返回它注册的可调用对象。

关于python - 在 python 中实现观察者模式的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44499490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com