从pyh看Python的工厂模式

来源:互联网 发布:ubuntu rar命令 编辑:程序博客网 时间:2024/05/21 14:56

【设想】

在做selenium前端页面测试时,想到生成html报告,需要编写个类,实现在Python内编辑html,具体思路如下:

1、编写各种tag类型,如head、title、body;

2、重载 + 运算,实现类似html + head的功能;

想到第一点,当时就觉得繁琐,要定义如此多个类(原谅我当时傻傻的),后来发现个开源项目:https://pypi.python.org/pypi/PyH/0.1

【PyH工厂模式解析】

PyH就一个源码pyh.py,很简单,以下截取部分代码分析,请尊重原作者,不要直接使用

定义一个基础类,并重载+操作符,重载<<重载符

class Tag(list):    tagname = ''        def __init__(self, *arg, **kw):        self.attributes = kw        if self.tagname :             name = self.tagname            self.isSeq = False        else:             name = 'sequence'            self.isSeq = True        self.id = kw.get('id', name)        #self.extend(arg)        for a in arg: self.addObj(a)    def __iadd__(self, obj):        if isinstance(obj, Tag) and obj.isSeq:            for o in obj: self.addObj(o)        else: self.addObj(obj)        return self        def addObj(self, obj):        if not isinstance(obj, Tag): obj = str(obj)        id=self.setID(obj)        setattr(self, id, obj)        self.append(obj)    def setID(self, obj):        if isinstance(obj, Tag):            id = obj.id            n = len([t for t in self if isinstance(t, Tag) and t.id.startswith(id)])        else:            id = 'content'            n = len([t for t in self if not isinstance(t, Tag)])        if n: id = '%s_%03i' % (id, n)        if isinstance(obj, Tag): obj.id = id        return id    def __add__(self, obj):        if self.tagname: return Tag(self, obj)        self.addObj(obj)        return self    def __lshift__(self, obj):        self += obj        if isinstance(obj, Tag): return obj    def render(self):        result = ''        if self.tagname:            result = '<%s%s%s>' % (self.tagname, self.renderAtt(), self.selfClose()*' /')        if not self.selfClose():            for c in self:                if isinstance(c, Tag):                    result += c.render()                else: result += c            if self.tagname:                 result += '</%s>' % self.tagname        result += '\n'        return result    def renderAtt(self):        result = ''        for n, v in self.attributes.iteritems():            if n != 'txt' and n != 'open':                if n == 'cl': n = 'class'                result += ' %s="%s"' % (n, v)        return result    def selfClose(self):        return self.tagname in selfClose        

然后定义工厂类

def TagFactory(name):    class f(Tag):        tagname = name    f.__name__ = name    return f

最后实现工厂模式

for t in tags: setattr(thisModule, t, TagFactory(t)) 

【PyH生成html】

#生成一个page对象report_html = PyH(ur'乐视页面测试报告')'''可以使用<<运算符往page类添加tag节点,可添加的如下tags = ['html', 'body', 'head', 'link', 'meta', 'div', 'p', 'form', 'legend',         'input', 'select', 'span', 'b', 'i', 'option', 'img', 'script',        'table', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',        'fieldset', 'a', 'title', 'body', 'head', 'title', 'script', 'br', 'table',        'ul', 'li', 'ol']'''report_html << h1(u'乐视页面测试报告',cl='header1',style='color:red; text-align:center')#Tag对象,也可以使用<<往里面添加节点myul = report_html << ul(cl='ul_report')logintb = myul << table(cl='tb_login',border=2)logintb << tr(cl='tb_tr') << td(cl='tb_login_head') << p(u'登录测试用例: 1 个',style='color:blue; text-align:center')#最后使用printOut输出到文件或者consolereport_html.printOut('result.html') 


0 0