python项目实践.docx
《python项目实践.docx》由会员分享,可在线阅读,更多相关《python项目实践.docx(20页珍藏版)》请在冰豆网上搜索。
python项目实践
python项目练习一:
即时标识表记标帜60837°C之宇文皓月创作
这是《python基础教程》后面的实践,照着写写,一方面是来熟悉python的代码方式,另一方面是练习使用python中的基本的以及非基本的语法,做到熟能生巧。
这个项目一开始比较简单,不过重构之后就有些复杂了,但是更灵活了。
依照书上所说,重构之后的程序,分为四个模块:
处理程序模块,过滤器模块,规则(其实应该是处理规则),语法分析器。
先来说处理程序模块,这个模块的作用有两个,一个是提供那些固定的html标识表记标帜的输出(每一个标识表记标帜都有start和end),另一个是对这个标识表记标帜输出的开始和结束提供了一个友好的访问接口。
来看下程序handlers.py:
classHandler:
'''
'''
defcallback(self,prefix,name,*args):
method=getattr(self,prefix+name,None)
ifcallable(method):
returnmethod(*args)
defstart(self,name):
self.callback('start_',name)
defend(self,name):
self.callback('end_',name)
defsub(self,name):
defsubstitution(match):
result=self.callback('sub_',name,match)
ifresultisNone:
match.group(0)
returnresult
returnsubstitution
classHTMLRenderer(Handler):
'''
'''
defstart_document(self):
print'
...'
defend_document(self):
print''
defstart_paragraph(self):
print'
'
defend_paragraph(self):
print'
'
defstart_heading(self):
print'
'
defend_heading(self):
print''
defstart_list(self):
print'
'defend_list(self):
print'
'
defstart_listitem(self):
print'
'defend_listitem(self):
print'
'
defstart_title(self):
print'
'
defend_title(self):
print''
defsub_emphasis(self,match):
return'%s'%match.group
(1)
defsub_url(self,match):
return'%s'%(match.group
(1),match.group
(1))
defsub_mail(self,match):
return'%s">%s'%(match.group
(1),match.group
(1))
deffeed(self,data):
printdata
这个程序堪称是整个“项目”的基石所在:
提供了标签的输出,以及字符串的替换。
理解起来也比较简单。
再来看第二个模块“过滤器”,这个模块更为简单,其实就是一个正则表达式的字符串。
相关代码如下:
self.addFilter(r'\*(.+?
)\*','emphasis')
self.addFilter(r'(http:
//[\.az09AZ/]+)','url')
self.addFilter(r'([\.azAZ]+@[\.azAZ]+[azAZ]+)','mail')
这就是三个过滤器了,分别是:
强调牌过滤器(用×号标出的),url牌过滤器,email牌过滤器。
熟悉正则表达式的同学理解起来是没有压力的。
再来看第三个模块“规则”,这个模块,抛开那祖父类不说,其他类应该有的两个方法是condition和action,前者是用来判断读进来的字符串是不是符合自家规则,后者是用来执行操纵的,所谓的执行操纵就是指调用“处理程序模块”,输出前标签、内容、后标签。
来看下这个模块的代码,其实这个里面几个类的关系,画到类图里面看会比较清晰。
rules.py:
classRule:
defaction(self,block,handler):
handler.start(self.type)
handler.feed(block)
handler.end(self.type)
returnTrue
classHeadingRule(Rule):
type='heading'
defcondition(self,block):
returnnot'\n'inblockandlen(block)<=70andnotblock[1]==':
'
classTitleRule(HeadingRule):
type='title'
first=True
defcondition(self,block):
ifnotself.first:
returnFalse
self.first=False
returnHeadingRule.condition(self,block)
classListItemRule(Rule):
type='listitem'
defcondition(self,block):
returnblock[0]==''
defaction(self,block,handler):
handler.start(self.type)
handler.feed(block[1:
].strip())
handler.end(self.type)
returnTrue
classListRule(ListItemRule):
type='list'
inside=False
defcondition(self,block):
returnTrue
defaction(self,block,handler):
ifnotself.insideandListItemRule.condition(self,block):
handler.start(self.type)
self.inside=True
elifself.insideandnotListItemRule.condition(self,block):
handler.end(self.type)
self.inside=False
returnFalse
classParagraphRule(Rule):
type='paragraph'
defcondition(self,block):
returnTrue
弥补utils.py:
defline(file):
forlineinfile:
yieldline
yield'\n'
defblocks(file):
block=[]
forlineinlines(file):
ifline.strip():
block.append(line)
elifblock:
yield''.join(block).strip()
block=[]
最后隆重的来看下“语法分析器模块”,这个模块的作用其实就是协调读入的文本和其他模块的关系。
在往重点说就是,提供了两个存放“规则”和“过滤器”的列表,这么做的好处就是使得整个程序的灵活性得到了极大的提高,使得规则和过滤器酿成的热插拔的方式,当然这个也归功于前面在写规则和过滤器时每一种类型的规则(过滤器)都单独的写成了一个类,而不是用if..else来区分。
看代码:
importsys,re
fromhandlersimport*
fromutilimport*
fromrulesimport*
classParser:
def__init__(self,handler):
self.handler=handler
self.rules=[]
self.filters=[]
defaddRule(self,rule):
self.rules.append(rule)
defaddFilter(self,pattern,name):
deffilter(block,handler):
returnre.sub(pattern,handler.sub(name),block)
self.filters.append(filter)
defparse(self,file):
self.handler.start('document')
forblockinblocks(file):
forfilterinself.filters:
block=filter(block,self.handler)
forruleinself.rules:
ifrule.condition(block):
last=rule.action(block,self.handler)
iflast:
break
self.handler.end('document')
classBasicTextParser(Parser):
def__init__(self,handler):
Parser.__init__(self,handler)
self.addRule(ListRule())
self.addRule(ListItemRule())
self.addRule(TitleRule())
self.addRule(HeadingRule())
self.addRule(ParagraphRule())
self.addFilter(r'\*(.+?
)\*','emphasis')
self.addFilter(r'(http:
//[\.az09AZ/]+)','url')
self.addFilter(r'([\.azAZ]+@[\.azAZ]+[azAZ]+)','mail')
handler=HTMLRenderer()
parser=BasicTextParser(handler)
parser.parse(sys.stdin)
这个模块里面的处理思路是,遍历客户端(也就是程序执行的入口)给插进去的所有的规则和过滤器,来处理读进来的文本。
有一个细节的地方也要说一下,其实是和前面写的呼应一下,就是在遍历规则的时候通过调用condition这个东西来判断是否符合当前规则。
我觉得这个程序很像是命令行模式,有空可以复习一下该模式,以坚持记忆网节点的牢固性。
最后说一下我以为的这个程序的用途,1、用来做代码高亮分析,如果改写成js版的话,可以做一个在线代码编辑器。
2、可以用来学习,供我写博文用。
还有其他的思路,可以留下您的真知灼见。
弥补一个类图,很简陋,但是应该能说明之间的关系。
另外我还是建议如果看代码捋不清关系最好自己画图,自己画图才干熟悉整个结构。
python项目练习二:
画幅好画
作者:
the5fire|标签:
pythonpdf python实战 |发布:
12183:
35p.m.
这是《python基础教程》中的第二个项目,关于python操纵PDF
涉及到的知识点
∙1、urllib的使用
∙2、reportlab库的使用
这个例子着实很简单,不过我发现在python里面可以直接在数组[]里面写for循环,真是越用越方便。
下面是代码:
fromurllibimporturlopen
fromreportlab.graphics.shapesimport*
fromreportlab.graphics.charts.lineplotsimportLinePlot
fromreportlab.graphics.charts.textlabelsimportLabel
fromreportlab.graphicsimportrenderPDF
URL='http:
//www.swpc.noaa.gov/ftpdir/weekly/Predict.txt'
COMMENT_CHARS='#:
'
drawing=Drawing(400,200)
data=[]
forlineinurlopen(URL).readlines():
ifnotline.isspace()andnotline[0]inCOMMENT_CHARS:
data.append([float(n)forninline.split()])
pred=[row[2]forrowindata]
high=[row[3]forrowindata]
low=[row[4]forrowindata]
times=[row[0]+row[1]/12.0forrowindata]
lp=LinePlot()
lp.x=50
lp.y=50
lp.height=125
lp.width=300
lp.data=[zip(times,pred),zip(times,high),zip(times,low)]
lp.lines[0].strokeColor=colors.blue
lp.lines[1].strokeColor=colors.red
lp.lines[2].strokeColor=colors.green
drawing.add(lp)
drawing.add(String(250,150,'Sunspots',fontSize=14,fillColor=colors.red))
renderPDF.drawToFile(drawing,'report3.pdf','Sunspots')
python项目练习三:
万能的XML
作者:
the5fire|标签:
python实战 |发布:
12203:
18p.m.
这个项目的名称与其叫做万能的XML不如叫做自动构建网站,根据一份XML文件,生成对应目录结构的网站,不过只有html还是太过于简单了,如果要是可以连带生成css那就比较强大了。
这个有待后续研发,先来研究下怎么html网站结构。
既然是通过XML结构生成网站,那所有的事情都应该由这个XML文件来。
先来看下这个XML文件,website.xml:
WelcometomyHomepage
Hi,there.MynameisMr.gumby,andthisismyhomepage,herearesomeofmyint:
shoutingpage
....
sleepingpage
...
Eatingpage
....
有了这个文件,下面应该来看怎么通过这个文件生成网站。
首先我们要解析这个xml文件,python解析xml和在java中一样,有两种方式,SAX和DOM,两种处理方式分歧点在于速度和范围,前者讲究的是效率,每次只处理文档的一小部分,快速而能有效的利用内存,后者是相反的处理方式,先把所有的文档载入到内存,然后再进行处理,速度比较慢,也比较消耗内存,唯一的好处就是可以操纵整个文档。
在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler,后面的这个类是要和parse函数来配合使用的。
使用方式如下:
parse('xxx.xml',xxxHandler),这里面的xxxHandler要继承上面的ContentHandler,不过只要继承就行,不需要有所作为。
然后这个parse函数在处理xml文件的时候,会调用xxxHandler中的startElement函数和endElement函数来一个xml中的标签的开始和结束,中间的过程使用一个名为characters的函数来处理标签内部的所有字符串。
有了上面的这些认识,我们已经知道如何处理xml文件了,然后再来看那个罪恶的源头website.xml文件,分析其结构,只有两个节点:
page和directory,很明显page暗示一个页面,directory暗示一个目录。
所以处理这个xml文件的思路就变的清晰了。
读取xml文件的每一个节点,然后判断是page还是directory如果是page则创建html页面,然后把节点中的内容写到文件里。
如果遇到directory就创建一个文件夹,然后再处理其内部的page节点(如果存在的话)。
下面来看这部分代码,书中的实现比较复杂,比较灵活。
先来看,然后在分析。
fromxml.sax.handlerimportContentHandler
fromxml.saximportparse
importos
classDispatcher:
defdispatch(self,prefix,name,attrs=None):
mname=prefix+name.capitalize()
dname='default'+prefix.capitalize()
method=getattr(self,mname,None)
ifcallable(method):
args=()
else:
method=getattr(self,dname,None)
args=name,
ifprefix=='start':
args+=attrs,
ifcallable(method):
method(*args)
defstartElement(self,name,attrs):
self.dispatch('start',name,attrs)
defendElement(self,name):
self.dispatch('end',name)
classWebsiteConstructor(Dispatcher,ContentHandler):
passthrough=False
def__init__(self,directory):
self.directory=[directory]
self.ensureDirectory()
defensureDirectory(self):
path=os.path.join(*self.directory)
printpath
print''
ifnotos.path.isdir(path):
os.makedirs(path)
defcharacters(self,chars):
ifself.passthrough:
self.out.write(chars)
defdefaultStart(self,name,attrs):
ifself.passthrough:
self.out.write('<'+name)
forkey,valinattrs.items():
self.out.write('%s="%s"'%(key,val))
self.out.write('>')
defdefaultEnd(self,name):
ifself.passthrough:
self.out.write('%s>'%name)
defstartDirectory(self,attrs):
self.directory.append(attrs['name'])
self.ensureDirectory()
defendDirectory(self):
print'endDirectory'
self.directory.pop()
defstartPage(self,attrs):
print'startPage'
filename=os.path.join(*self.directory+[attrs['name']+'.html'])
self.out=open(filename,'w')
self.writeHeader(attrs['title'])
self.passthrough=True
defendPage(self):
print'endPage'
self.passthrough=False
self.writeFooter()
self.out.close()
defwriteHeader(self,title):
self.out.