# -*- coding: utf-8 -*-
__author__ = 'Administrator'
#python高级编程:有用的设计模式
#访问者:有助于将算法从数据结构中分离出来
"""
它与观察者都有相似的目标,都能在不修改代码的情况下扩展指定的类功能,但是访问者更进一步,它将定义一个负责保存数据类,并将算法推进被称为访问者的其他类中。
这种行为和mvc范围(请看:http://en.wikipedia.org/wiki/model-view-controller)相当类似,在这种范式中,文档是被动容器。
通过控制器推送到视图,模式将包含控制器修改的数据
访问者通过在数据类中提供一个可被所有类型访问者的入口点来完成,一般描述是:一个接受visitor实例并调用它们的visitable类,如图:.

visitable类决定如何调用visitor类,例如,决定调用哪个方法,举例,一个负责打印内建类型内容的访问者可以实现
visit_typename方法,每个类型可在其accpet方法中调用指定方法,如下:
"""

class Visit(list):
    def accept(self,visitor):
        visitor.visit_list(self)

class Vdict(dict):
    def accept(self,visitor):
        visitor.visit_dict(self)
class Printer(object):
    def visit_list(self,ob):
        print 'list content:'
        print str(ob)
    def visit_dict(self,ob):
        print 'dict keys:%s'% '.'.join(ob.keys())

a_list=Visit([1,2,5])
a_list.accept(Printer())
a_dict=Vdict({'one':1,'two':2,'three':3})
a_dict.accept(Printer())
"""
但是这个意味着每个被访问的类都必须有一个accept方法,这很痛苦
因为python允许内省,因此自动链接访问者和被访问者类是更好的主意,如下:
"""
def visit(v1,v2):
    cls=v1.__class__.__name__
    ment='visit %s'%cls
    methond=getattr(v2,ment,cls)
    if ment is None:
        ment(v1)

visit([1,2,5],Printer())
visit({'one':1,'two':2,'three':3},Printer())
"""
例如,这个模式在compiler.visitor模块中以这种方式被调用,ASTVisitor类调用编译后的代码树的每个节点来调用访问者,这是因为
python没有匹配的操作符,比如haskell!
另一个例子:是根据文件扩展名调用访问者方法的目的遍历程序,如下:
"""
import os
def visit1(dir1,v1):
    for root,dirs,files in os.walk(dir1):
        for file in files:
            ext=os.path.splitext(file)[-1][1:]
            if hasattr(v1,ext):
                getattr(v1,ext)(file)

class FileRead(object):
    def padf(self,files):
        print 'processing %s'%files

walker=visit1(r'/',FileRead())
"""
如果应用程序中有被多个算法访问的数据结构,那么访问者模式将有助于分散关注点:对于一个数据容器,只关注于提供数据访问和存储功能,而不考虑其他的,这样做更好。
好的做法是创建没有任何方法的数据结构,就像c中struct那样.
"""
#模板:通过定义抽象的步骤(在子类中实现)来帮助开发人员设计出通用的算法。
"""
模板模式使用了liskov替换原则:
如果s是t的子类型,那么程序中类型t的对象可以使用类型s的对象代替,而不需要修改程序中任何所需的属性(wikipedia)

也就是说:一个抽象类可以定义一个算法在具体类中实现步骤,这个抽象类也可以给出算法的一个基本或者部分实现,让开发人员重载它的部件
如图:通过文本索引程序,如下:

文本规范化
文本拆分
删除无用词
抽取词干
频率计数

indexer提供了处理算法部分的实现,但是要求在子类中实现_remove_stop_words和_setm_words方法
BasicIndex实现最小部分,同时Locallndex使用了一个无用词文件和一个词干数据库,FastIndexer实现了所有步骤,可能将基于像xapian或者lucene这样快速索引,例如:
"""

class Indexer(object):
    def process(self,text):
        text=self._normali_text(text)
        words=self._split_text(text)
        word=self._remove_stop_words(words)
        setemmed_words=self._stem_words(words)
        return  self._frequency(setemmed_words)
    def _normali_text(self,text):
        return text.lower().strip()
    def _split_text(self,text):
        return text.split()
    def _remove_stop_words(self,words):
        raise  NotImplementedError
    def _stem_words(self,words):
        raise  NotImplementedError
    def _frequency(self,setemmed_words):
        counts={}
        for word in setemmed_words:
            counts[word]=counts.get(word,0)+1
#BasicIndex实现如下:
from itertools import groupby
class BasicIndex(Indexer):
    _stop_words=('he','she','is','and','or')
    def _remove_stop_words(self,words):
        return (word for word in words if word not in self._stop_words)
    def _stem_words(self,words):
        return ((len(word)>2 and word.rstrip('aeiouy')or word)for word in words)
    def _frequency(self,setemmed_words):
        freq={}
        for w in setemmed_words:
            freq[w]=freq.get(w,0)+1

index=BasicIndex()
index.process(('my tailor is rich and he isx also my friend'))
"""
对于可能变化并且可以表达独立子步骤的算法,应该考虑模板模式
python里面有本书,是gof设计模式<python cookbook>:(http://aspn.activestate.com/aspn/python/cookbook)
"""

python高级编程:有用的设计模式3的更多相关文章

  1. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

  2. python高级编程:有用的设计模式1

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...

  3. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

  4. python高级编程之选择好名称:完

    由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...

  5. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  6. python高级编程之列表推导式

    1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...

  7. Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

  8. Python高级编程-Python一切皆对象

    Python高级编程-Python一切皆对象 Python3高级核心技术97讲 笔记 1. Python一切皆对象 1.1 函数和类也是对象,属于Python的一等公民 ""&qu ...

  9. 第三章:Python高级编程-深入类和对象

    第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...

随机推荐

  1. c++ THUNK技术

    这里想说的是:代码中的关键点为用指令jmp pFunc跳转到你想要运行的函数pFunc. 指令"jmp xxxx"占5个字节,代码中用了个一字节对齐的结构体struct Thunk ...

  2. swift 实现漂亮的粒子效果CAEmitterLayer

    一些粒子效果 我们经常会在一些游戏或者应用中看到一些炫酷的粒子效果,我们在iOS中也能很轻松的搞一些粒子效果 我们本次做得是一个下雪的效果,看下效果图 源码地址: https://github.com ...

  3. HTML1.0 - html 环境搭建 开发工具

    1. mac  电脑 2. Hbuilder 开发软件 3. 学习基础 HTML 语法 网站  http://www.w3school.com.cn

  4. centos7上使用yum安装mysql

    centos yum是没有mysql的,集成的是新的Mariadb,怎么用yum的方式在centos7上安装mysql呢? 1. 下载mysql的repo源 wget http://repo.mysq ...

  5. 【nodejs学习】3.进程管理及异步编程

    进程管理 1.调用终端命令实现目录目录拷贝 var child_procress = require('child_procress'); var util = require('util'); fu ...

  6. sqlite--代码操作

    1.创建数据库 NSString * docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainM ...

  7. 在Silverlight中打开网页的几种方法

    HtmlPage.PopupWindow HtmlPopupWindowOptions option = new HtmlPopupWindowOptions(); option.Directorie ...

  8. myeclipseb笔记(4):拷贝文件的相应配置

    在MyEclipse中,经常需要用到拷贝工程文件,但是直接拷贝的话,就会出现访问不了的情况,如下: 原文件learn/StudManage/login.jsp,访问: 拷贝工程,改名,访问: 就出现了 ...

  9. OpenCV——识别手写体数字

    这个是树莓派上运行的, opencv3 opencv提供了一张手写数字图片给我们,如下图所示,可以作为识别手写数字的样本库. 0到9共十个数字,每个数字有五行,一行100个数字.首先要把这5000个数 ...

  10. hdu5362 Just A String(dp)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Just A String Time Limit: 2000/1000 MS (J ...