Python设计模式之观察者模式实例


Posted in Python onApril 26, 2014

关于设计模式中的观察者模式,定义如下(维基百科):

?察者模式(有?r又被??榘l布/??模式)是????模式的一?。在此?模式中,一??目?宋锛?芾硭?邢嘁漓端?挠^察者物件,?K且在它本身的??B改??r主?影l出通知。?通常透?呼叫各?察者所提供的方法????。此?模式通常被用???作事件?理系?。
简单来说,一个被观察者有很多观察者,被观察者的状态的改变会引起所有观察者的响应操作。

那么我们用Python2.7来实现观察者模式。

Python中的集合set

集合(set),类似于列表(list),但是它没有重复的元素,它的doc内容如下:

>>> print set.__doc__
set() -> new empty set object
set(iterable) -> new set object
Build an unordered collection of unique elements.

下面是在ipython中进行的几个简单的集合操作。
In [1]: myset = set()
In [2]: myset.add(1)
In [3]: myset.add(2)
In [4]: myset.add('s')
In [5]: print myset
set([1, 2, 's'])
In [6]: myset.add('s')
In [7]: print myset
set([1, 2, 's'])
In [8]: myset.remove(3)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-8-a93073f8a2af> in <module>()
----> 1 myset.remove(3)
KeyError: 3
In [9]: myset.remove(1)
In [10]: print myset
set([2, 's'])

通过内置的set()可以产生一个空的集合对象,也可以在set中传入一些参数,例如一个列表:
>>> print set([1,2,3,3])
set([1, 2, 3])

最常用的方法就是add和remove了,更多内容可以参考http://docs.python.org/2/library/stdtypes.html#set。

一个简单的观察者模式的实现

class Observer(object):
    def __init__(self, s):
        self.s = s
    def update(self):
        print self.s
if __name__ == '__main__':
    foo01 = Observer("hi, i am foo01")
    foo02 = Observer("hi, i am foo02")
    observers = set()
    observers.add(foo01)
    observers.add(foo01)
    observers.add(foo02)
    print observers
    for ob in observers:
        ob.update()

下面是运行结果:
set([<__main__.Observer object at 0xb74627cc>, <__main__.Observer object at 0xb74627ec>])
hi, i am foo01
hi, i am foo02

运行结果中第一行是集合observers的内容,其包含了两个Observer实例,这些实例所处的内存地址在每次运行时可能有不同。而
for ob in observers:
    ob.update()

就可以看成多个观察者产生响应。

当然,这种实现并不好——被观察者也应该是一个实例。

更加完善的观察者模式实现

class ObserverInterface(object):
    def __init__(self):
        pass
    def update(self):
        pass
class SubjectInterface(object):
    def __init__(self):
        self.observers = set()
    def addObserver(self, ob):
        self.observers.add(ob)
    def delObserver(self, ob):
        self.observers.remove(ob)
    def notifyObservers(self):
        for ob in self.observers:
            ob.update()
class Observer01(ObserverInterface):
    def __init__(self, s):
        self.s = s
    def update(self):
        print self.s
class Observer02(ObserverInterface):
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2
    def update(self):
        print self.num1 + self.num2
class Subject01(SubjectInterface):
    def __init__(self):
        SubjectInterface.__init__(self)
if __name__ == '__main__':
    ob01 = Observer01("hi, i am ob01")
    ob02 = Observer02("hello,","i am ob02")
    observers = set()
    sb01 = Subject01()
    sb01.addObserver(ob01)
    sb01.addObserver(ob02)
    sb01.notifyObservers()

运行结果如下:
hi, i am ob01
hello,i am ob02
Python 相关文章推荐
python 生成目录树及显示文件大小的代码
Jul 23 Python
一些Python中的二维数组的操作方法
May 02 Python
Python爬取数据并写入MySQL数据库的实例
Jun 21 Python
在python下读取并展示raw格式的图片实例
Jan 24 Python
Python获取网段内ping通IP的方法
Jan 31 Python
python利用Opencv实现人脸识别功能
Apr 25 Python
Pandas实现dataframe和np.array的相互转换
Nov 30 Python
Python hashlib模块实例使用详解
Dec 24 Python
Python3自动生成MySQL数据字典的markdown文本的实现
May 07 Python
Anaconda详细安装步骤图文教程
Nov 12 Python
Requests什么的通通爬不了的Python超强反爬虫方案!
May 20 Python
Pytest中skip和skipif的具体使用方法
Jun 30 Python
Python设计模式之代理模式实例
Apr 26 #Python
python中的列表推导浅析
Apr 26 #Python
Python中的Numpy入门教程
Apr 26 #Python
Python中的map、reduce和filter浅析
Apr 26 #Python
Python实现的Kmeans++算法实例
Apr 26 #Python
爬山算法简介和Python实现实例
Apr 26 #Python
Python操作sqlite3快速、安全插入数据(防注入)的实例
Apr 26 #Python
You might like
据说是雅虎的一份PHP面试题附答案
2009/01/07 PHP
PHP判断网络文件是否存在的方法
2015/03/12 PHP
php中使用sftp教程
2015/03/30 PHP
经典PHP加密解密函数Authcode()修复版代码
2015/04/05 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
2017/07/16 PHP
JavaScript CSS修改学习第一章 查找位置
2010/02/19 Javascript
非阻塞动态加载javascript广告实现代码
2010/11/17 Javascript
尝试在让script的type属性等于text/html
2013/01/15 Javascript
js/jquery获取文本框输入焦点的方法
2014/03/04 Javascript
JS 获取鼠标左右键的键值方法
2014/10/11 Javascript
javascript记录文本框内文字个数检测文字个数变化
2014/10/14 Javascript
javascript中基本类型和引用类型的区别分析
2015/05/12 Javascript
浅谈JavaScript中的Math.atan()方法的使用
2015/06/14 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
功能强大的Bootstrap效果展示(二)
2016/08/03 Javascript
js 点击a标签 获取a的自定义属性方法
2016/11/21 Javascript
JS多物体实现缓冲运动效果示例
2016/12/20 Javascript
过期软件破解办法实例详解
2017/01/04 Javascript
jQuery输入框密码的显示隐藏【代码分享】
2017/04/29 jQuery
js 两数组去除重复数值的实例
2017/12/06 Javascript
基于模板引擎Jade的应用(详解)
2017/12/12 Javascript
jQuery中的$是什么意思及 $. 和 $().的区别
2018/04/20 jQuery
react quill中图片上传由默认转成base64改成上传到服务器的方法
2019/10/30 Javascript
OpenLayers加载缩放控件使用方法详解
2020/09/25 Javascript
python判断给定的字符串是否是有效日期的方法
2015/05/13 Python
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
使用python 爬虫抓站的一些技巧总结
2018/01/10 Python
pygame游戏之旅 添加icon和bgm音效的方法
2018/11/21 Python
如何基于Python爬虫爬取美团酒店信息
2020/11/03 Python
UNIX文件系统分类
2014/11/11 面试题
前台接待岗位职责
2013/12/03 职场文书
预备党员群众路线教育实践活动思想汇报2014
2014/10/25 职场文书
2014年团支部工作总结
2014/11/17 职场文书
Pytorch 如何实现常用正则化
2021/05/27 Python
《LOL》“克隆大作战”久违归来 幻灵战队皮肤上线
2022/04/03 其他游戏