从pyh看Python的工厂模式
【设想】
在做selenium前端页面测试时,想到生成html报告,需要编写个类,实现在Python内编辑html,具体思路如下:
1、编写各种tag类型,如head、title、body;
2、重载+运算,实现类似html+head的功能;
想到第一点,当时就觉得繁琐,要定义如此多个类(原谅我当时傻傻的),后来发现个开源项目:https://pypi.python.org/pypi/PyH/0.1
【PyH工厂模式解析】
PyH就一个源码pyh.py,很简单,以下截取部分代码分析,请尊重原作者,不要直接使用
定义一个基础类,并重载+操作符,重载<<重载符
[python]viewplaincopy
classTag(list):
tagname=''
def__init__(self,*arg,**kw):
self.attributes=kw
ifself.tagname:
name=self.tagname
self.isSeq=False
else:
name='sequence'
self.isSeq=True
self.id=kw.get('id',name)
#self.extend(arg)
forainarg:self.addObj(a)
def__iadd__(self,obj):
ifisinstance(obj,Tag)andobj.isSeq:
foroinobj:self.addObj(o)
else:self.addObj(obj)
returnself
defaddObj(self,obj):
ifnotisinstance(obj,Tag):obj=str(obj)
id=self.setID(obj)
setattr(self,id,obj)
self.append(obj)
defsetID(self,obj):
ifisinstance(obj,Tag):
id=obj.id
n=len([tfortinselfifisinstance(t,Tag)andt.id.startswith(id)])
else:
id='content'
n=len([tfortinselfifnotisinstance(t,Tag)])
ifn:id='%s_%03i'%(id,n)
ifisinstance(obj,Tag):obj.id=id
returnid
def__add__(self,obj):
ifself.tagname:returnTag(self,obj)
self.addObj(obj)
returnself
def__lshift__(self,obj):
self+=obj
ifisinstance(obj,Tag):returnobj
defrender(self):
result=''
ifself.tagname:
result='<%s%s%s>'%(self.tagname,self.renderAtt(),self.selfClose()*'/')
ifnotself.selfClose():
forcinself:
ifisinstance(c,Tag):
result+=c.render()
else:result+=c
ifself.tagname:
result+='</%s>'%self.tagname
result+='\n'
returnresult
defrenderAtt(self):
result=''
forn,vinself.attributes.iteritems():
ifn!='txt'andn!='open':
ifn=='cl':n='class'
result+='%s="%s"'%(n,v)
returnresult
defselfClose(self):
returnself.tagnameinselfClose
然后定义工厂类
[python]viewplaincopy
defTagFactory(name):
classf(Tag):
tagname=name
f.__name__=name
returnf
最后实现工厂模式
[python]viewplaincopy
fortintags:setattr(thisModule,t,TagFactory(t))
【PyH生成html】
[python]viewplaincopy
#生成一个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输出到文件或者console
report_html.printOut('result.html')