资源描述
python项目练习一:即时标记 60837°C
这就是《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 substitution
class HTMLRenderer(Handler):
'''
'''
def start_document(self):
print '<html><head><title>、、、</title></head><body>'
def end_document(self):
print '</body></html>'
def start_paragraph(self):
print '<p>'
def end_paragraph(self):
print '</p>'
def start_heading(self):
print '<h2>'
def end_heading(self):
print '</h2>'
def start_list(self):
print '<ul>'
def end_list(self):
print '</ul>'
def start_listitem(self):
print '<li>'
def end_listitem(self):
print '</li>'
def start_title(self):
print '<h1>'
def end_title(self):
print '</h1>'
def sub_emphasis(self, match):
return '<em>%s</em>' % match、group(1)
def sub_url(self, match):
return '<a href="%s">%s</a>' % (match、group(1),match、group(1))
def sub_mail(self, match):
return '<a href="mailto:%s">%s</a>' % (match、group(1),match、group(1))
def feed(self, data):
print data
这个程序堪称就是整个“项目”得基石所在:提供了标签得输出,以及字符串得替换。理解起来也比较简单。
再来瞧第二个模块“过滤器”,这个模块更为简单,其实就就是一个正则表达式得字符串。相关代码如下:
self、addFilter(r'\*(、+?)\*', 'emphasis')
self、addFilter(r'(://[\、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 True
class 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 block[0] == '-'
def action(self,block,handler):
handler、start(self、type)
handler、feed(block[1:]、strip())
handler、end(self、type)
return True
class 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 False
class ParagraphRule(Rule):
type = 'paragraph'
def condition(self, block):
return True
补充utils、py:
def line(file):
for line in line
yield '\n'
def 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, re
from 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'(://[\、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项目练习二:画幅好画
作者:the5fire | 标签: pythonpdf python实战 | 发布:2011-12-18 3:35 p、m、
这就是《python基础教程》中得第二个项目,关于python操作PDF
涉及到得知识点
· 1、urllib得使用
· 2、reportlab库得使用
这个例子着实很简单,不过我发现在python里面可以直接在数组[]里面写for循环,真就是越用越方便。
下面就是代码:
from urllib import urlopen
from reportlab、graphics、shapes import *
from reportlab、graphics、charts、lineplots import LinePlot
from reportlab、graphics、charts、textlabels import Label
from reportlab、graphics import renderPDF
URL = ''
MENT_CHARS = '#:'
drawing = Drawing(400, 200)
data = []
for line in urlopen(URL)、readlines():
if not line、isspace() and not line[0] in MENT_CHARS:
data、append([float(n) for n in line、split()])
pred = [row[2] for row in data]
high = [row[3] for row in data]
low = [row[4] for row in data]
times = [row[0] + row[1]/12、0 for row in data]
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、drawTo, 'report3、pdf','Sunspots')
python项目练习三:万能得XML
作者:the5fire | 标签: python实战 | 发布:2011-12-20 3:18 p、m、
这个项目得名称与其叫做万能得XML不如叫做自动构建网站,根据一份XML文件,生成对应目录结构得网站,不过只有html还就是太过于简单了,如果要就是可以连带生成css那就比较强大了。这个有待后续研发,先来研究下怎么html网站结构。 既然就是通过XML结构生成网站,那所有得事情都应该由这个XML文件来。先来瞧下这个XML文件,website、xml:
<website>
<page name="index" title="Home page">
<h1>Wele to my Home page</h1>
<p>Hi, there、 My name is Mr、gumby,and this is my home page,here are some of my int:</p>
<ul>
<li><a href="interests/shouting、html">Shouting</a></li>
<li><a href="interests/sleeping、html">Sleeping</a></li>
<li><a href="interests/eating、html">Eating</a></li>
</ul>
</page>
<directory name="interests">
<page name="shouting" title="Shouting">
<h1>shouting page</h1>
<p>、、、、</p>
</page>
<page name="sleeping" title="Sleeping">
<h1>sleeping page</h1>
<p>、、、</p>
</page>
<page name="eating" title="Eating">
<h1>Eating page</h1>
<p>、、、、</p>
</page>
</directory>
</website>
有了这个文件,下面应该来瞧怎么通过这个文件生成网站。
首先我们要解析这个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 ContentHandler
from xml、sax import parse
import os
class 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('<' + name)
for key, val in attrs、items():
self、out、write(' %s="%s"' %(key, val))
self、out、write('>')
def defaultEnd(self, name):
if self、passthrough:
self、out、write('</%s>' % name)
def startDirectory(self, attrs):
self、directory、append(attrs['name'])
self、ensureDirectory()
def endDirectory(self):
print 'endDirectory'
self、directory、pop()
def startPage(self, attrs):
print 'startPage'
= os、path、join(*self、directory + [attrs['name']+'、html'])
self、out = open(, 'w')
self、writeHeader(attrs['title'])
self、passthrough = True
def endPage(self):
print 'endPage'
self、passthrough = False
self、writeFooter()
self、out、close()
def writeHeader(self, title):
self、out、write('<html>\n <head>\n <title>')
self、out、write(title)
self、out、write('</title>\n </head>\n <body>\n')
def writeFooter(self):
self、out、write('\n </body>\n</html>\n')
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项目练习四:新闻聚合
作者:the5fire | 标签: python实战 | 发布:2011-12-26 2:07 p、m、
书中得第四个练习,新闻聚合。现在很少见得一类应用,至少我从来没有用过,又叫做Usenet。这个程序得主要功能就是用来从指定得来源(这里就是Usenet新闻组)收集信息,然后讲这些信息保存到指定得目得文件中(这里使用了两种形式:纯文本与html文件)。这个程序得用处有些类似于现在得博客订阅工具或者叫RSS订阅器。
先上代码,然后再来逐一分析:
from nntplib import NNTP
from time import strftime,time,localtime
from email import message_from_string
from urllib import urlopen
import textwrap
import re
day = 24*60*60
def wrap(string,max=70):
'''
'''
return '\n'、join(textwrap、wrap(string)) + '\n'
class 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 = body
class 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 = message['subject']
body = message、get_payload()
if message、is_multipart():
body = body[0]
yield NewsItem(title,body)
server、quit()
class SimpleWebSource:
def __init__(self,url,titlePattern,bodyPattern):
self、url = url
self、titlePattern = re、pile(titlePattern)
self、bodyPattern = re、pile(bodyPattern)
def getItems(self):
text = urlopen(self、url)、read(
展开阅读全文