




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
python项目练习一:即时标记 60837C 这是python基础教程后面的实践,照着写写,一方面是来熟悉python的代码方式,另一方面是练习使用python中的基本的以及非基本的语法,做到熟能生巧。这个项目一开始比较简单,不过重构之后就有些复杂了,但是更灵活了。按照书上所说,重构之后的程序,分为四个模块:处理程序模块,过滤器模块,规则(其实应该是处理规则),语法分析器。先来说处理程序模块,这个模块的作用有两个,一个是提供那些固定的html标记的输出(每一个标记都有start和end),另一个是对这个标记输出的开始和结束提供了一个友好的访问接口。来看下程序handlers.py:class Handler: def 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 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): 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, match): 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)这就是三个过滤器了,分别是:强调牌过滤器(用号标出的),url牌过滤器,email牌过滤器。熟悉正则表达式的同学理解起来是没有压力的。再来看第三个模块“规则”,这个模块,抛开那祖父类不说,其他类应该有的两个方法是condition和action,前者是用来判断读进来的字符串是不是符合自家规则,后者是用来执行操作的,所谓的执行操作就是指调用“处理程序模块”,输出前标签、内容、后标签。 来看下这个模块的代码,其实这个里面几个类的关系,画到类图里面看会比较清晰。 rules.py:class Rule: def action(self, block, handler): handler.start(self.type) handler.feed(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 = False 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 = 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 Falseclass 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 = 最后隆重的来看下“语法分析器模块”,这个模块的作用其实就是协调读入的文本和其他模块的关系。在往重点说就是,提供了两个存放“规则”和“过滤器”的列表,这么做的好处就是使得整个程序的灵活性得到了极大的提高,使得规则和过滤器变成的热插拔的方式,当然这个也归功于前面在写规则和过滤器时每一种类型的规则(过滤器)都单独的写成了一个类,而不是用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.filters = 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: block = 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() 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)这个模块里面的处理思路是,遍历客户端(也就是程序执行的入口)给插进去的所有的规则和过滤器,来处理读进来的文本。有一个细节的地方也要说一下,其实是和前面写的呼应一下,就是在遍历规则的时候通过调用condition这个东西来判断是否符合当前规则。我觉得这个程序很像是命令行模式,有空可以复习一下该模式,以保持记忆网节点的牢固性。最后说一下我以为的这个程序的用途, 1、用来做代码高亮分析,如果改写成js版的话,可以做一个在线代码编辑器。 2、可以用来学习,供我写博文用。还有其他的思路,可以留下您的真知灼见。补充一个类图,很简陋,但是应该能说明之间的关系。另外我还是建议如果看代码捋不清关系最好自己画图,自己画图才能熟悉整个结构。python项目练习二:画幅好画 22982C 作者:the5fire | 标签: pythonpdf python实战 | 发布:2011-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 LinePlotfrom reportlab.graphics.charts.textlabels import Labelfrom reportlab.graphics import renderPDFURL = /ftpdir/weekly/Predict.txtCOMMENT_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 for 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.lines2.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实战 | 发布:2011-12-20 3:18 p.m. 这个项目的名称与其叫做万能的XML不如叫做自动构建网站,根据一份XML文件,生成对应目录结构的网站,不过只有html还是太过于简单了,如果要是可以连带生成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 . 有了这个文件,下面应该来看怎么通过这个文件生成网站。首先我们要解析这个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节点(如果存在的话)。下面来看这部分代码,书中的实现比较复杂,比较灵活。先来看,然后在分析。from xml.sax.handler import ContentHandlerfrom xml.sax import parseimport osclass Dispatcher: def dispatch(self, prefix, name, attrs=None): mname = prefix + name.capitalize() 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 endElement(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): 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) self.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 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)看起来这个程序上面分析的复杂了一些,不过伟人毛毛说过,任何复杂的程序都是纸老虎。那我们再来分析一下这个程序。首先看到这个程序是有两个类,其实完全可以当作一个类,因为有了继承。然后再来看它多了些什么,除了我们分析出来的startElement和endElement以及characters,多出来了startPage,endPage;startDirectory,endDirectory;defaultStart,defaultEnd;ensureDirectory;writeHeader,writeFooter;和dispatch,这些个函数。除了dispatch,前面的函数都很好理解,每一对函数都是单纯的处理对应的html标签以及xml节点。而dispatch比较复杂,复杂之处在于他是用来动态拼合函数并且进行执行的。dispatch的处理思路是,首先根据传递的参数(就是操作名称以及节点名称)判断是否存在对应的函数如startPage,如果不存在则执行default+操作名称:如defaultStart。一个函数一个函数搞清楚之后,就知道整个处理流程是什么样了。首先创建一个public_html的文件,存放整个网站,然后读xml的节点,通过startElement和endElement调用dispatch进行处理。然后就是dispatch怎么调用具体的处理函数了。 到此为止,这个项目算是分析完了。主要掌握的内容一个是python中使用SAX处理XML,另一个就是python中的函数的使用,比如getattr,传参数时的星号python项目练习四:新闻聚合 13729C 作者:the5fire | 标签: python实战 | 发布:2011-12-26 2:07 p.m. 书中的第四个练习,新闻聚合。现在很少见的一类应用,至少我从来没有用过,又叫做Usenet。这个程序的主要功能是用来从指定的来源(这里是Usenet新闻组)收集信息,然后讲这些信息保存到指定的目的文件中(这里使用了两种形式:纯文本和html文件)。这个程序的用处有些类似于现在的博客订阅工具或者叫RSS订阅器。先上代码,然后再来逐一分析:from nntplib import NNTPfrom time import strftime,time,localtimefrom 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 addDestination(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 _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,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(text) bodies = self.bodyPattern.findall(text) for title.body in zip(titles,bodies): yield NewsItem(title,wrap(body)class PlainDestination: def receiveItems(self,items): for item in items: print item.title print -*len(item.title) print item.bodyclass HTMLDestination: def _init_(self,filename): self.filename = filename def receiveItems(self,items): out = open(self.filename,w) print out, Todays News Todays News print out, id = 0 for item in items: id += 1 print out, %s % (id,item.title) print out, id = 0 for item in items: id += 1 print out, %s % (id,item.title) print out, %s % item.body print out, def runDefaultSetup(): agent = NewsAgent() bbc_url = http:/news.bbc.co.uk/text_only.stm bbc_title = r(?s)a href=*s*s*(.*?)s* bbc_body = r(?s)s*s*(.*?)s* bbc = SimpleWebSource(bbc_url, bbc_title, bbc_body) agent.addSource(bbc) clpa_server = news2.neva.ru clpa_group = alt.sex.telephone clpa_window = 1 clpa = NNTPSource(clpa_server,clpa_group,clpa_window) agent.addSource(clpa) agent.addDestination(PlainDestination() agent.addDestination(HTMLDestination(news.html) agent.distribute()if _name_ = _main_: runDefaultSetup()这个程序,首先从整体上进行分析,重点部分在于NewsAgent,它的作用是存储新闻来源,存储目标地址,然后在分别调用来源服务器(NNTPSource以及SimpleWebSource)以及写新闻的类(PlainDestination和HTMLDestination)。所以从这里也看的出,NNTPSource是专门用来获取新闻服务器上的信息的,SimpleWebSource是获取一个url上的数据的。而PlainDestination和HTMLDestination的作用很明显,前者是用来输出获取到的内容到终端的,后者是写数据到html文件中的。有了这些分析,然后在来看主程序中的内容,主程序就是来给NewsAgent添加信息源和输出目的地址的。这确实是个简单的程序,不过这个程序可是用到了分层了。python项目练习五:虚拟茶话会 11638C 作者:the5fire | 标签: python实战,socket编程 | 发布:2011-12-30 3:31 p.m. 几乎在学习、使用任何一种编程语言的时候,关于socket的练习从来都不会少,尤其是会写一些局域网的通信的东西。所以书上的这个项目刚好可以练习一下socket编程。这个练习的整体思路首先有一个聊天的服务器,这个服务器的功能主要是提供客户端socket的连接、存储每个客户端的连接session,处理每个连接发送的消息、解析客户端发送的数据。就这些,至于客户端方面不需要写代码,用系统的telnet工具即可。我觉得有了上面的分析,剩
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 仿金网格图钉项目投资可行性研究分析报告(2024-2030版)
- 2025年中国高档羊毛方向盘套行业市场发展前景及发展趋势与投资战略研究报告
- 2025年中国水晶哑光瓷片行业市场发展前景及发展趋势与投资战略研究报告
- 2025年中国金卤灯行业市场运营现状及投资方向研究报告
- 2025年中国耳机线行业市场调查研究及投资前景预测报告
- 箱体框架项目投资可行性研究分析报告(2024-2030版)
- 2025年转子泵项目可行性分析报告
- 重组腺病毒-VEGF行业深度研究分析报告(2024-2030版)
- 2025至2030中国煤制化肥行业发展趋势分析与未来投资战略咨询研究报告
- 2025至2030中国流动电话回收服务行业发展趋势分析与未来投资战略咨询研究报告
- 汽车的总体构造课件
- 眼科护理中的医疗事故与风险管理
- 煤矿岗位标准化作业流程
- 《合理使用抗生素》课件
- 数字美的智慧工业白皮书-2023.09
- 桥梁施工进度图
- 某啤酒厂安全现状评价设计报告书模板
- 广西桂林市2022-2023学年高二下学期期末质量检测数学试题(含答案解析)
- 内墙抹灰安全技术交底
- 中学美术校本教材《素描》
- 《幼儿生活活动保育》课程标准
评论
0/150
提交评论