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

相关推荐