1、python项目练习一:即时标记 60837C 这是python基本教程背面实践,照着写写,一方面是来熟悉python代码方式,另一方面是练习使用python中基本以及非基本语法,做到熟能生巧。这个项目一开始比较简朴,但是重构之后就有些复杂了,但是更灵活了。按照书上所说,重构之后程序,分为四个模块:解决程序模块,过滤器模块,规则(其实应当是解决规则),语法分析器。先来说解决程序模块,这个模块作用有两个,一种是提供那些固定html标记输出(每一种标记均有start和end),另一种是对这个标记输出开始和结束提供了一种和谐访问接口。来看下程序handlers.py:class Handler: d
2、ef callback(self,prefix,name,*args): method = getattr(self,prefix+name,None) if callable(method):return method(*args) def start(self,name): self.callback(start_,name) def end(self,name): self.callback(end_,name) def sub(self,name): def substitution(match): result = self.callback(sub_,name,match) if
3、result is None:match.group(0) return result return substitutionclass HTMLRenderer(Handler): def start_document(self): print . def end_document(self): print def start_paragraph(self): print def end_paragraph(self): print def start_heading(self): print def end_heading(self): print def start_list(self)
4、: print def end_list(self): print def start_listitem(self): print def end_listitem(self): print def start_title(self): print def end_title(self): print def sub_emphasis(self,match): return %s % match.group(1) def sub_url(self, match): return %s % (match.group(1),match.group(1) def sub_mail(self, mat
5、ch): return %s % (match.group(1),match.group(1) def feed(self,data): print data这个程序堪称是整个“项目”基石所在:提供了标签输出,以及字符串替代。理解起来也比较简朴。再来看第二个模块“过滤器”,这个模块更为简朴,其实就是一种正则表达式字符串。有关代码如下:self.addFilter(r*(.+?)*,emphasis)self.addFilter(r(http:/.a-z0-9A-Z/+),url)self.addFilter(r(.a-zA-Z+.a-zA-Z+a-zA-Z+),mail)这就是三个过滤器了,分
6、别是:强调牌过滤器(用号标出),url牌过滤器,email牌过滤器。熟悉正则表达式同窗理解起来是没有压力。再来看第三个模块“规则”,这个模块,抛开那祖父类不说,其她类应当有两个办法是condition和action,前者是用来判断读进来字符串是不是符合自家规则,后者是用来执行操作,所谓执行操作就是指调用“解决程序模块”,输出前标签、内容、后标签。 来看下这个模块代码,其实这个里面几种类关系,画到类图里面看会比较清晰。 rules.py:class Rule: def action(self,block,handler): handler.start(self.type) handler.fee
7、d(block) handler.end(self.type) return Trueclass HeadingRule(Rule): type = heading def condition(self,block): return not n in block and len(block) = 70 and not block-1 = :class TitleRule(HeadingRule): type = title first = True def condition(self,block): if not self.first:return False self.first = Fa
8、lse return HeadingRule.condition(self,block)class ListItemRule(Rule): type = listitem def condition(self,block): return block0 = - def action(self,block,handler): handler.start(self.type) handler.feed(block1:.strip() handler.end(self.type) return Trueclass ListRule(ListItemRule): type = list inside
9、= False def condition(self,block): return True def action(self,block,handler): if not self.inside and ListItemRule.condition(self,block): handler.start(self.type) self.inside = True elif self.inside and not ListItemRule.condition(self,block): handler.end(self.type) self.inside = False return Falsecl
10、ass ParagraphRule(Rule): type = paragraph def condition(self,block): return True补充utils.py:def line(file): for line in file:yield line yield ndef blocks(file): block = for line in lines(file): if line.strip(): block.append(line) elif block: yield .join(block).strip() block = 最后隆重来看下“语法分析器模块”,这个模块作用其
11、实就是协调读入文本和其她模块关系。在往重点说就是,提供了两个存储“规则”和“过滤器”列表,这样做好处就是使得整个程序灵活性得到了极大提高,使得规则和过滤器变成热插拔方式,固然这个也归功于前面在写规则和过滤器时每一种类型规则(过滤器)都单独写成了一种类,而不是用if.else来区别。 看代码:import sys,refrom handlers import *from util import *from rules import *class Parser: def _init_(self,handler): self.handler = handler self.rules = self.f
12、ilters = def addRule(self,rule): self.rules.append(rule) def addFilter(self,pattern,name): def filter(block,handler): return re.sub(pattern,handler.sub(name),block) self.filters.append(filter) def parse(self,file): self.handler.start(document) for block in blocks(file): for filter in self.filters: b
13、lock = filter(block,self.handler) for rule in self.rules: if rule.condition(block): last = rule.action(block,self.handler) if last:break self.handler.end(document)class BasicTextParser(Parser): def _init_(self,handler): Parser._init_(self,handler) self.addRule(ListRule() self.addRule(ListItemRule()
14、self.addRule(TitleRule() self.addRule(HeadingRule() self.addRule(ParagraphRule() self.addFilter(r*(.+?)*,emphasis) self.addFilter(r(http:/.a-z0-9A-Z/+),url) self.addFilter(r(.a-zA-Z+.a-zA-Z+a-zA-Z+),mail)handler = HTMLRenderer()parser = BasicTextParser(handler)parser.parse(sys.stdin)这个模块里面解决思路是,遍历客户
15、端(也就是程序执行入口)给插进去所有规则和过滤器,来解决读进来文本。有一种细节地方也要说一下,其实是和前面写呼应一下,就是在遍历规则时候通过调用condition这个东西来判断与否符合当前规则。我觉得这个程序很像是命令行模式,有空可以复习一下该模式,以保持记忆网节点牢固性。最后说一下我觉得这个程序用途, 1、用来做代码高亮分析,如果改写成js版话,可以做一种在线代码编辑器。 2、可以用来学习,供我写博文用。尚有其她思路,可以留下您真知灼见。补充一种类图,很简陋,但是应当能阐明之间关系。此外我还是建议如果看代码捋不清关系最佳自己画图,自己画图才干熟悉整个构造。python项目练习二:画幅好画 2
16、2982C 作者:the5fire | 标签: pythonpdf python实战 | 发布:-12-18 3:35 p.m. 这是python基本教程中第二个项目,关于python操作PDF涉及到知识点 1、urllib使用 2、reportlab库使用这个例子着实很简朴,但是我发当前python里面可以直接在数组里面写for循环,真是越用越以便。下面是代码:from urllib import urlopenfrom reportlab.graphics.shapes import *from reportlab.graphics.charts.lineplots import Line
17、Plotfrom reportlab.graphics.charts.textlabels import Labelfrom reportlab.graphics import renderPDFURL = COMMENT_CHARS = #:drawing = Drawing(400,200)data = for line in urlopen(URL).readlines():if not line.isspace() and not line0 in COMMENT_CHARS:data.append(float(n) for n in line.split()pred = row2 f
18、or row in datahigh = row3 for row in datalow = row4 for row in datatimes = row0 + row1/12.0 for row in datalp = LinePlot()lp.x = 50lp.y = 50lp.height = 125lp.width = 300lp.data = zip(times,pred),zip(times,high),zip(times,low)lp.lines0.strokeColor = colors.bluelp.lines1.strokeColor = colors.redlp.lin
19、es2.strokeColor = colors.greendrawing.add(lp)drawing.add(String(250,150,Sunspots,fontSize=14,fillColor=colors.red)renderPDF.drawToFile(drawing,report3.pdf,Sunspots)python项目练习三:万能XML 13869C 作者:the5fire | 标签: python实战 | 发布:-12-20 3:18 p.m. 这个项目名称与其叫做万能XML不如叫做自动构建网站,依照一份XML文献,生成相应目录构造网站,但是只有html还是太过于简朴
20、了,如果要是可以连带生成css那就比较强大了。这个有待后续研发,先来研究下怎么html网站构造。 既然是通过XML构造生成网站,那所有事情都应当由这个XML文献来。先来看下这个XML文献,website.xml: Welcome to my Home page Hi,there. My name is Mr.gumby,and this is my home page,here are some of my int: Shouting Sleeping Eating shouting page . sleeping page . Eating page . 有了这个文献,下面应当来看怎么通过这
21、个文献生成网站。一方面咱们要解析这个xml文献,python解析xml和在java中同样,有两种方式,SAX和DOM,两种解决方式不同点在于速度和范畴,前者讲究是效率,每次只解决文档一小某些,迅速而能有效运用内存,后者是相反解决方式,先把所有文档载入到内存,然后再进行解决,速度比较慢,也比较消耗内存,唯一好处就是可以操作整个文档。在python中使用sax方式解决xml要先引入xml.sax中parse函数,尚有xml.sax.handler中ContentHandler,背面这个类是要和parse函数来配合使用。使用方式如下: parse(xxx.xml,xxxHandler),这里面xxx
22、Handler要继承上面ContentHandler,但是只要继承就行,不需要有所作为。 然后这个parse函数在解决xml文献时候,会调用xxxHandler中startElement函数和endElement函数来一种xml中标签开始和结束,中间过程使用一种名为characters函数来解决标签内部所有字符串。有了上面这些结识,咱们已经懂得如何解决xml文献了,然后再来看那个罪恶源头website.xml文献,分析其构造,只有两个节点:page和directory,很明显page表达一种页面,directory表达一种目录。因此解决这个xml文献思路就变清晰了。读取xml文献每一种节点,然
23、后判断是page还是directory如果是page则创立html页面,然后把节点中内容写到文献里。如果遇到directory就创立一种文献夹,然后再解决其内部page节点(如果存在话)。下面来看这某些代码,书中实现比较复杂,比较灵活。先来看,然后在分析。from xml.sax.handler import ContentHandlerfrom xml.sax import parseimport osclass Dispatcher: def dispatch(self,prefix,name,attrs=None): mname = prefix + name.capitalize()
24、dname = default + prefix.capitalize() method = getattr(self,mname,None) if callable(method):args = () else: method = getattr(self,dname,None) args = name, if prefix = start:args += attrs, if callable(method):method(*args) def startElement(self,name,attrs): self.dispatch(start,name,attrs) def endElem
25、ent(self,name): self.dispatch(end,name)class WebsiteConstructor(Dispatcher,ContentHandler): passthrough = False def _init_(self,directory): self.directory = directory self.ensureDirectory() def ensureDirectory(self): path = os.path.join(*self.directory) print path print - if not os.path.isdir(path):
26、os.makedirs(path) def characters(self,chars): if self.passthrough:self.out.write(chars) def defaultStart(self,name,attrs): if self.passthrough: self.out.write() def defaultEnd(self,name): if self.passthrough: self.out.write( % name) def startDirectory(self,attrs): self.directory.append(attrsname) se
27、lf.ensureDirectory() def endDirectory(self): print endDirectory self.directory.pop() def startPage(self,attrs): print startPage filename = os.path.join(*self.directory + attrsname+.html) self.out = open(filename,w) self.writeHeader(attrstitle) self.passthrough = True def endPage(self): print endPage
28、 self.passthrough = False self.writeFooter() self.out.close() def writeHeader(self,title): self.out.write(n n ) self.out.write(title) self.out.write(n n n) def writeFooter(self): self.out.write(n nn)parse(website.xml,WebsiteConstructor(public_html)看起来这个程序上面分析复杂了某些,但是伟人毛毛说过,任何复杂程序都是纸老虎。那咱们再来分析一下这个程序。
29、一方面看到这个程序是有两个类,其实完全可以当作一种类,由于有了继承。然后再来看它多了些什么,除了咱们分析出来startElement和endElement以及characters,多余来了startPage,endPage;startDirectory,endDirectory;defaultStart,defaultEnd;ensureDirectory;writeHeader,writeFooter;和dispatch,这些个函数。除了dispatch,前面函数都较好理解,每一对函数都是单纯解决相应html标签以及xml节点。而dispatch比较复杂,复杂之处在于她是用来动态拼合函数并且
30、进行执行。dispatch解决思路是,一方面依照传递参数(就是操作名称以及节点名称)判断与否存在相应函数如startPage,如果不存在则执行default+操作名称:如defaultStart。一种函数一种函数弄清晰之后,就懂得整个解决流程是什么样了。一方面创立一种public_html文献,存储整个网站,然后读xml节点,通过startElement和endElement调用dispatch进行解决。然后就是dispatch怎么调用品体解决函数了。 到此为止,这个项目算是分析完了。重要掌握内容一种是python中使用SAX解决XML,另一种就是python中函数使用,例如getattr,传
31、参数时星号python项目练习四:新闻聚合 13729C 作者:the5fire | 标签: python实战 | 发布:-12-26 2:07 p.m. 书中第四个练习,新闻聚合。当前很少见一类应用,至少我从来没有用过,又叫做Usenet。这个程序重要功能是用来从指定来源(这里是Usenet新闻组)收集信息,然后讲这些信息保存到指定目文献中(这里使用了两种形式:纯文本和html文献)。这个程序用处有些类似于当前博客订阅工具或者叫RSS订阅器。先上代码,然后再来逐个分析:from nntplib import NNTPfrom time import strftime,time,localti
32、mefrom email import message_from_stringfrom urllib import urlopenimport textwrapimport reday = 24*60*60def wrap(string,max=70): return n.join(textwrap.wrap(string) + nclass NewsAgent: def _init_(self): self.sources = self.destinations = def addSource(self,source): self.sources.append(source) def add
33、Destination(self,dest): self.destinations.append(dest) def distribute(self): items = for source in self.sources: items.extend(source.getItems() for dest in self.destinations: dest.receiveItems(items)class NewsItem: def _init_(self,title,body): self.title = title self.body = bodyclass NNTPSource: def
34、 _init_(self,servername,group,window): self.servername = servername self.group = group self.window = window def getItems(self): start = localtime(time() - self.window*day) date = strftime(%y%m%d,start) hour = strftime(%H%M%S,start) server = NNTP(self.servername) ids = server.newnews(self.group,date,
35、hour)1 for id in ids: lines = server.article(id)3 message = message_from_string(n.join(lines) title = messagesubject body = message.get_payload() if message.is_multipart(): body = body0 yield NewsItem(title,body) server.quit()class SimpleWebSource: def _init_(self,url,titlePattern,bodyPattern): self.url = url self.titlePattern = pile(titlePattern) self.bodyPattern = pile(bodyPattern) def getItems(self): text = urlopen(self.url).read() titles = self.titlePattern.findall(te