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

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

解决方案

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 #

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)

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.do_something

>

>>> type(bar.do_something)

>>> bar.do_something.__self__

[edit: decorator example]

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值