创建简单的Python列表
movies=[‘The HolyGrail’,
‘The Life of Brian’,
‘The Meaning of Life’]
(1)在列表两边加引号,将各个电影名转换为字符串
(2)用逗号将列表项与下一项分隔开
(3)在列表的两边加上开始和结束中括号[]
(4)使用赋值操作符(=)将这个列表赋至一个标识符(以上代码中的movies)
用标准的中括号偏移量记法来访问一个列表槽中的数据项
代码:“”“
>>>print(movies[1])
The Life of Brian
>>>cast=['Cleese','Palin','Jones','Idle']
>>>print(cast)
['Cleese', 'Palin','Jones', 'Idle']
>>>print(len(cast)) #得出列表有多少个数据项
4
>>>print(cast[1])
Palin
““”
常用“.”(点记法)来调用方法
代码:““”
>>>cast.append('Gilliam') #在列表末尾增加一个数据项
>>>print(cast) #检查效果
['Cleese', 'Palin','Jones', 'Idle', 'Gilliam']
>>>cast.pop() #在列表末尾删除数据
'Gilliam'
>>>print(cast) #检查效果
['Cleese', 'Palin', 'Jones','Idle']
>>>cast.extend(['Gilliam','Chapman']) #在列表末尾增加一个数据项集合
>>>print(cast) #检查效果
['Cleese', 'Palin','Jones', 'Idle', 'Gilliam', 'Chapman']
>>>cast.remove('Chapman') #在列表中找到并删除一个特定的数据项
>>>print(cast) #检查效果
['Cleese', 'Palin','Jones', 'Idle', 'Gilliam']
>>>cast.remove('Palin') #在列表中找到并删除一个特定的数据
>>>print(cast) #检查效果
['Cleese', 'Jones','Idle', 'Gilliam']
>>>cast.insert(0,'Chapman') #第一个参数代表位置,第二个参数代表要加入的数据,加到位置前面
>>>cast.insert(2,'Palin')
>>>print(cast) #检查效果
['Chapman', 'Cleese','Palin', 'Jones', 'Idle', 'Gilliam']
>>> movies
['The Holy Grail','The Life of Brian', 'The Meaning of Life']
>>>movies.insert(1,1975) #插入数据
>>>movies.insert(3,1979) #插入数据
>>>movies.append(1983) #在列表后面添加数据
>>>print(movies) #检查效果
['The Holy Grail', 1975,'The Life of Brian', 1979, 'The Meaning of Life', 1983]
“”“
处理列表数据
迭代
代码:“”“
>>>fav_movies=['The Holy Grail', 'The Life of Brian'] #定义一个列表并填充它
>>> for each_flick in fav_movies:
print(each_flick) #使用for循环迭代处理列表,在这个过程中得各个列表项的值显示在屏幕上
使用for循环是可伸缩的,适用于任意大小的列表
““”
for 循环
for 目标标识符 in 列表:
列表处理代码
Python的for循环是为了处理列表和Python中的其他迭代结构。
while语句
代码:“”“
count=0
while count<len(movies):
print(movies[count])
count=count+1
““”
使用“while”时,必须考虑“状态信息”,这就要求使用一个计数标识符(例子中的count)。
while与for循环比较:
代码:“”“
for each_item in movies:
print(each_item)
““”
使用“for“时,将由Python解释器为你考虑”状态信息“。
>>>movies=['The Holy Grail',1975,'Terry Jone&Terry Gilliam',91,['GrahamChapman',['Michael Palin','John Cleese','Terry Gilliam','EricIdle','Terry Jones']]]
>>> print(movies[4][1][3])#列表第4的位置,列表第1的位置,列表第3的位置(位置从0开始)
Eric Idle
>>> for each_item in movies:
print(each_item)
在列表中查找列表(用if语句)
if 某个条件满足:
“true”组
else:
“false”组
代码:“”“
>>> foreach_item in movies: #for循环检查每个位置,处理第1重列表
if isinstance(each_item,list): #内置函数isinstance()允许检查某个标识符是否包含某个特定类型的数据
for nested_item in each_item: #for循环检查每个位置,处理第2重列表
if isinstance(nested_item,list): #3重列表,2个判断。如果有更多的列表,需要写更多的判断
for deeper_item in nested_item: #for循环检查每个位置,处理第3重列表
print(deeper_item) #打印第3重列表的元素
else:
print(nested_item) #打印第2重列表的元素
else: #2个if,2个else
print(each_item) #打印第1重列表的元素
““”
函数
不要重复代码;应当创建一个函数
def 函数名(参数):
函数代码组
代码:“”“
>>> defprint_lol(the_list): #定义函数名和参数
for each_item in the_list: #检查每一个位置
if isinstance(each_item,list): #检查当前位置是不是一个列表
print_lol(each_item)#条件成立,调用函数
else:#条件不成立
print(each_item)#打印出来
>>> print_lol(movies) #把movies扔进参数的位置
““”
命名空间
>>>cast=['Palin','Cleese','Idle','Jones','Gilliam','Chapman'] #写一个列表
>>> importnester #导入模块
>>> nester.print_lol(cast) #点号将模块命名空间与函数名分割开
使用一个普通的import语句时,如import nester,这会指示Python解释器
允许你使用命名空间限定来访问nester的函数。
如果遇到一个需求,而且你认为这个需求很普遍,
先问问自己有没有一个内置函数(BIF)可以提供帮助。
list()这是一个工厂函数,创建一个新的空列表
range()返回一个迭代器,根据需要生成一个指定范围的数字
enumerate()创建成对数据的一个编号列表,从0开始
int()将一个字符串或另一个数转换成一个整数(如果可行)
id()返回一个Python数据对象的唯一标识
next()返回一个可迭代数据结构(如列表)中的下一项
range迭代固定次数
代码:“”“
>>> for numin range(4):
print(num) #生成数字0,1,2,3
““”
使用可选参数
"""
这是“nester.py”模块,提供一个名为print_lol()的函数
用来打印列表,其中包含或不包含嵌套列表。
"""
def print_lol(the_list,indent=False,level=0):
"""
这个函数有一个位置参数,名为"the_list",
这可以是任何Python列表(包含或不包含嵌套列表),
所提供列表中的各个数据项会(递归地)打印到屏幕上,而且各占一行。
第二个参数(名为"level")用来在遇到嵌套列表中插入制表符。
"""
for each_item in the_list:
if isinstance(each_item,list):
print_lol(each_item,indent,level+1)#签名已经改变,所以一定要更新“indent”
else:
if indent: #判断是否要缩进
for tab_stop in range(level): #缩进多少
print("\t",end='') #range控制缩进符的数量
"""
print("\t"*level,end='')
"""
print(each_item)
为了将一个函数的必要参数变成可选的参数,需要为这个参数提供一个缺省值。
如果没有参数值,就会使用这个缺省值。如果提供一个参数值,则会使用这个值而不是缺省值。
defprint_lol(the_list,level=0):
包含end=’’作为print()BIF的一个参数会关闭其默认行为(即在输入中自行包含换行)。
文件与异常
Python中的基本输入机制都是基于行的:
从文本文件向程序读入数据时,一次会到达一个数据行。
Python的open()BIF就是用来与文件交互的。
如果与for语句结合使用,可以非常容易地读取文件。
代码:“”“
>>> importos #从标准库导入“os”
>>> os.getcwd() #查看当前的工作目录
>>> os.chdir('F:\有趣的事\Python\HeadFirstPython\chapter3') #切换到包含数据文件的文件夹
>>>data=open('sketch.txt') #打开文件,将文件赋至一个名为“data”的文件对象
>>>print(data.readline(),end='') #读取一个数据行,不换行
Man: Is this theright room for an argument? #效果
>>>print(data.readline(),end='') #读取一个数据行,不换行
Other Man: I've toldyou once. #效果
>>>data.seek(0) #使用seek()方法返回到文件起始位置
0
>>> foreach_line in data:
print(each_line,end='') #这是一个标准的迭代,这里使用了文件数据作为输入
>>>data.close()#关闭文件,注意有小括号的
>>>each_line="I tell you,there's no such thing as a flying circus."
>>>each_line.find(':') #找不到显示-1
-1
>>>each_line="I tell you:there's no such thing as a flying circus."
>>>each_line.find(':') #找得到,返回其所在的位置,从0开始数
10
import os
ifos.path.exists("sketch.txt"): #如果这个路径存在这个文件
data=open('sketch.txt') #条件成立,打开文件
for each_line in data:
if each_line.find(':')!=-1: #判断是否由“:”
#ifnot each_line.find(':')==-1
(role,line_spoken)=each_line.split(":",1) #分割成2部分
print(role,end='')
print(' said:',end='')
print(line_spoken,end='')
data.close() #一定要关
else:
print("The data file ismissing!")
““”
放过错误
代码:“”“
data=open('sketch.txt')
for each_line in data:
try:
(role,line_spoken)=each_line.split(":",1)
print(role,end='')
print('said:',end='')
print(line_spoken,end='')
except:
pass
data.close()
““”
现在,不论调用split()方法时发生什么,try语句会捕获所有异常并处理,
用pass忽略这个错误。
复杂性通常不是个好东西
随着你必须考虑的错误越来越多,“增加额外代码和逻辑”方案的复杂性也随之增加,
直到最后可能掩盖程序的本来作用。
而异常处理方案不存在这个问题,可以一目了然地看出程序的主要作用。
通过使用Python的异常处理机制,你可以关注代码真正需要做什么,而不必操心哪里可能出现问题,
并编写额外的代码来避免运行时错误。
谨慎地使用try语句可以让代码更易读,更易写,而且可能这是最重要的——出问题更容易修正。
要重点关注你的代码需要做什么。
持久存储
>>>out=open('data.txt','w') #以写的模式打开文件
>>>print('Norwegian Blues stun easily.',file=out) #’…’为写至文件的内容,out为所写的数据文件对象的名
>>>out.close() #这在写入文件时,非常重要。一定要关闭文件。
使用访问模式w时,Python会打开指定的文件来完成写。
如果这个文件已经存在,则会清空它现有的内容,也就是完全清除。
错误的细节
>>> try:
data=open('missing.txt')
print(data.readline(),end='')
except IOError as err:
print('File error'+str(err)) #err为错误的细节
finally:
if 'data' in locals():
data.close()
File error[Errno 2]No such file or directory: 'missing.txt'
总的代码
代码:“”“
man=[]
other=[] #新建2个空列表,来添加内容
try:
data=open('sketch.txt') #打开文件,赋至data这个对象
for each_line in data: #处理每一行
try: #放过错误
(role,line_spoken)=each_line.split(":",1) #用“:”作为分离的依据,分成role和line_spoken两部分
line_spoken=line_spoken.strip() #去掉line_spoken后面的空格
if role=='Man': #判断,如果是man
man.append(line_spoken) #追加到列表man
elif role=='Other Man': #判断,如果是Other Man
other.append(line_spoken) #追加到列表other
except ValueError: #处理没有“:”分离的错误
pass #用pass做处理
data.close() #一定要关闭
except IOError: #处理找不到文件的错误
print("The data file ismissing!") #打印友好信息
try:
man_file=open("man_data.txt","w") #写一个文件,赋至man_file这个对象
other_file=open("other_data.txt","w") #写一个文件,赋至other_file这个对象
print(man,file=man_file) #把列表man的数据放进man_file里面
print(other,file=other_file) #把列表other的数据放进other_file里面
except IOError: #处理打不开的情况
print("File error")
finally: #finally表示不管上面的代码有没有错误,一定要关闭文件
man_file.close()
other_file.close()
““”
用with处理文件
使用with时,不再需要操心关闭打开的文件,因为Python解释器会自动为你考虑这一点。
代码:“”“
try:
with open('its.txt','w') as data:
print("我存在了!!!",file=data)
except IOError aserr:
print('File error:'+str(err))
““”
“腌制”数据
用dump保存,用load恢复
使用pickle很简单:只需导入所需的模块,然后使用dump()保存数据,
以后某个时间使用load()恢复数据。
处理腌制数据时的唯一要求是,
必须以二进制访问模式打开文件。
print()签名如下:
print(value,sep=’’,end=’\n’,file=sys.stdout)
file参数控制将数据发送/保存在哪里。
as关键字赋至一个标识符。
str()BIF可以用来访问任何数据对象(支持串转换)的串表示。
in操作符用于检查成员关系。
“+”操作符用于字符串时,将连接两个字符串;用于数字时,则会将两个数相加。
代码:“”“
import pickle
withopen('mydata.pickle','wb') as mysavedata:
pickle.dump([1,2,'three'],mysavedata)
withopen('mydata.pickle','rb') as myrestoredata:
a_list=pickle.load(myrestoredata)
print(a_list)
““”
理解数据
sort()原地排序
sorted()复制排序
默认的,sort()方法和sorted()BIF都会按升序对数据排序。
要以降序对数据排序,需要向sort()或sorted()传入参数
reverse=True,Python会负责具体处理。
推导列表(1行语句)
clean_mikey=[]
for each_t in mikey:
clean_mikey.append(sanitize(each_t)) #前面由定义sanitize()函数
1行语句:
clean_mikey=[sanitize(each_t)for each_t in mikey]
(1)创建一个新列表来存放转换后的数据
(2)迭代处理原列表中的各个数据项
(3)每次迭代时完成转换
(4)将转换后的数据追加到新列表
代码:“”“
>>> mins=[1,2,3]
>>>sces=[m*60 for m in mins] #乘6
>>> sces
[60, 120, 180]
>>>meters=[1,10,3]
>>>feet=[m*3.28 for m in meters] #乘3.28
>>> feet
[3.28, 32.8, 9.84]
>>>lower=["I","don't","like","spam"]
>>>uppers=[s.upper() for s in lower] #小写转大写
>>> uppers
['I',"DON'T", 'LIKE', 'SPAM']
>>>dirty=['2-22','2:22','2.22']
>>>clean=[sanitize(time) for time in dirty] #利用函数转成统一形式
>>> clean
['2.22', '2.22','2.22']
>>>clean=[float(time) for time in clean] #字符串转成浮点数
>>> clean
[2.22, 2.22, 2.22]
>>> clean=[float(sanitize(time))for time in ['2-22','3:33','4.44']] #利用函数处理成统一形式,再转成浮点数
>>> clean
[2.22, 3.33, 4.44]
“方法串链”——从左向右读,对数据应用一组方法。
“函数串链”——从右向左读,对数据应用一组函数。
“分片”——从列表访问多个列表项。
要访问一个列表的多个数据项,可以使用分片。例如:my_list[3:6]
使用字典关联数据
如果你的数据有结构,就要使用字典,而不是列表。
首先创建两个空字典。
>>> cleese={}
>>> palin=dict()
通过将值与键关联,向这两个字典增加数据。
>>> cleese['Name']='John Cleese'
>>>cleese['Occupations']=['actor','comedian','writer','film producer']#在cleese中增加2个键和对应的值
>>> palin={'Name':'MichaelPalin','Occupation':['comedian','actor','writer','tv']} #在palin中增加2个键和值
>>> palin['Name'] #访问键’Name’对应的值
'Michael Palin'
>>> cleese['Occupations'][-1] #访问键’Occupations’对应的值的最后一个元素
'film producer'
>>>palin['Birthplace']='Broomhill,Sheffied,England' #增加一个键和值
>>> cleese['Birthplace']='England' #增加一个键和值
代码:“”“
def get_coach_data(filename): #函数,获取文件的数据
try:
with open(filename) as f:
data=f.readline()
return(data.strip().split(','))
exceptIOError as ioerr:
print('File error:'+str(ioerr))
return(None)
james=get_coach_data('james.txt') #4个数据赋至不同的对象
julie=get_coach_data('julie.txt')
mikey=get_coach_data('mikey.txt')
sarah=get_coach_data('sarah.txt')
import dispose_time
clean_james=[dispose_time.sanitize(each_t) foreach_t in james] #清理数据,转换成一样的形式
clean_julie=[dispose_time.sanitize(each_t) foreach_t in julie]
clean_mikey=[dispose_time.sanitize(each_t) foreach_t in mikey]
clean_sarah=[dispose_time.sanitize(each_t) foreach_t in sarah]
print(sorted(set(clean_james))[0:3]) #把列表转换成集合,去除相同的数据。再转换成列表,从小到大排列。选出第1和3
print(sorted(set(clean_julie))[0:3])
print(sorted(set(clean_mikey))[0:3])
print(sorted(set(clean_sarah))[0:3])
““”
使用class定义类
>>> class Athlete: #类定义从关键字class开始,’Athlete’为类指定一个合适的描述性的名字
def__init__(self,value=0): #不要忘记了加冒号,self必不可少
self.thing=value#现在‘初始化’代码,将所提供的值赋至一个名为“self.thing”的类属型
defhow_big(self): #“how_big()”方法返回“self.thing”的的长度
return(len(self.thing))
>>> d=Athlete('Holy Grail')
>>> d.how_big()
10
>>> class Athlete: #定义Athlete这个类,定义的时候没有括号没有值,表示不限定类型
def__init__(self,a_name,a_dob=None,a_time=[]): #属性对应的值在()里面,a_name的值要给,其他的都有默认值
self.name=a_name
self.dob=a_dob#默认值为“None”
self.time=a_time#默认值为空列表
>>> sarah=Athlete('SarahSweeney','2002-6-17',['2:58','2.58','1.56'])
>>> james=Athlete('James Jones')
>>> type(sarah)
<class '__main__.Athlete'> #Athlete这个类
>>> type(james)
<class '__main__.Athlete'>
>>> sarah
<__main__.Athlete object at0x0000016FA17EADD8> #位置
>>> james
<__main__.Athlete object at0x0000016FA17EAEB8>
>>> sarah.name #sarah调用类的属性name
'Sarah Sweeney'
>>> sarah.dob #sarah调用类的属性dob
'2002-6-17'
>>> sarah.time #sarah调用类的属性time
['2:58', '2.58', '1.56']
>>> james.dob #默认为None
>>> james.name #james调用类的属性name
'James Jones'
>>> james.time #默认为空列表
[]
>>> vera=Athlete('Vera Vi')
>>> vera.add_time('1.31')
>>> print(vera.top3())
['1.31']
>>>vera.add_times(['2.22','1-21','2:22']) #之前定义了add_times属性
>>> print(vera.top3())
['1.21', '1.31', '2.22']
>>> class NameList(list): #类里面有括号有值,限定为列表
def __init__(self,a_name):
list.__init__([]) #定义类本身是列表([])
self.name=a_name #定义类属性name是一个值,由参数list提供
>>> johnny=NameList('John Paul Jones')#运用类,a_name的值为’John Paul Jones’
>>> johnny.append('Bass Player') #增加一个字符串
>>>johnny.extend(['Composer','Arranger','Musician']) #增加一个列表
>>> johnny.name #调用类的属性name,返回a_name的值
'John Paul Jones'
>>> johnny
['Bass Player', 'Composer', 'Arranger','Musician']
>>> for attr in johnny:
print(johnny.name+'is a '+attr+".")
John Paul Jones is a Bass Player.
John Paul Jones is a Composer.
John Paul Jones is a Arranger.
John Paul Jones is a Musician.
类方法(代码)与函数定义基本相同,也就是说,要用def关键字定义。
可以在类中定义__init__()方法来初始化对象实例。
类中定义的每个方法都必须提供self,从而将数据与其实例关联。
类可以从零开始构建,也可以从Python的内置类或其他定制类继承。
总的处理数据
代码:“”“
模块:athletelist
class AthleteList(list):
#定义类AthleteList,本身是个列表,属性有name, dob和extend。参数a_name要填进去,其他都有默认值
def__init__(self,a_name,a_dob=None,a_time=[]):
list.__init__([])
self.name=a_name
self.dob=a_dob
self.extend(a_time)
deftop3(self): #方法:选出前3
return(sorted(set([sanitize(t) for t in self]))[0:3])
模块:athletemodel
import pickle
from athletelist import AthleteList
def get_coach_data(filename): #获取数据的函数
try:
with open(filename) as f: #打开文件,给个对象f
data=f.readline() #读取数据,给个对象data
templ=data.strip().split(',') #以“,”作为依据,分割数据。去掉后面的空格。给个对象templ
return(AthleteList(templ.pop(0),templ.pop(0),templ))#返回一个类对象,分离出templ的数据作为输入的参数
exceptIOError as ioerr: #处理异常情况
print('File error:'+str(ioerr))
def put_to_store(files_list): #“腌制”数据,储存起来
all_athletes={} #新建空字典
foreach_file in files_list: #files_list表示文件名列表,批量处理数据
ath=get_coach_data(each_file) #利用函数,获取数据
all_athletes[ath.name]=ath#属性name的值作为键,属性extend(a_time)作为值
return(all_athletes) #返回一个字典
try:
with open('athletes.pickle','wb') as athf: #以二进制写的模式创建文件,给一个对象
return(pickle.dump(all_athletes,athf))#把all_athlete的内容扔进文件里
exceptIOError as ioerr: #处理错误
print('File error(put_to_store):'+str(ioerr))
def get_from_store(): #恢复“腌制”的数据
all_athletes={} #新建一个空字典
try:
with open('athletes.pickle','rb') as athf: #以二进制的模式读取文件,给一个对象
all_athletes=pickle.load(athf)
exceptIOError as ioerr: #处理错误
print('File error(get_from_store):'+str(ioerr))
return(all_athletes)
““”
Web开发
CGI标准指出,每一个Web响应都必须有一个首部行来指出请求中包含的数据类型,
模块papy:
from string import Template
"""
从标准库的‘string’模块导入‘Template’类。它支持简单的字符串替换模板。
"""
def start_response(resp="text/html"):
return('Content-type: ' + resp + '\n\n')
"""
这个函数需要一个(可选的)字符串作为参数,用它来创建一个CGI‘Content-type:’行,
参数缺省值是‘text/html’。
"""
def include_header(the_title):
withopen('templates/header.html') as headf:
head_text = headf.read()
header= Template(head_text)
return(header.substitute(title=the_title))
"""
这个函数需要一个字符串作为参数,用在HTML页面最前面的标题中。
页面本身存储一个单独的文件‘template/header.html’中,可以根据需要替换标题。
"""
def include_footer(the_links):
withopen('templates/footer.html') as footf:
foot_text = footf.read()
link_string = ''
for keyin the_links:
link_string += '<a href="' + the_links[key] + '">' + key+ '</a> '
footer= Template(foot_text)
return(footer.substitute(links=link_string))
"""
与‘include_header’函数类似,这个函数使用一个字符串作为参数,来创建一个HTML页面的尾部。
页面本身存储在一个单独的文件‘template/footer.html’中,参数用于动态地创建一组HMTL链接标记。
从这些标记的使用来看,参数应当是一个字典。
"""
def start_form(the_url, form_type="POST"):
return('<form action="' + the_url + '" method="' +form_type + '">')
"""
这个函数返回表单最前面的HTML,允许调用者指定url(表单数据将发送到这个url),
还可以指定所要使用的方法。
"""
def end_form(submit_msg="Submit"):
return('<p></p><input type=submit value="' +submit_msg + '"></form>')
"""
这个函数返回表单末尾的HTML标记,同时还允许调用者定制表单‘submit’(提交)按钮的文本。
"""
def radio_button(rb_name, rb_value):
return('<input type="radio" name="' + rb_name +
'"value="' + rb_value + '"> ' + rb_value + '<br />')
"""
给定一个单选钮名和值,创建一个HTML单选钮(通常包括在HTML表单中)。注意:两个参数都是必要的。
"""
def u_list(items):
u_string= '<ul>'
foritem in items:
u_string += '<li>' + item + '</li>'
u_string += '</ul>'
return(u_string)
"""
给定一个项列表,这个函数会把该列表转换为一个HTML无序列表。
一个简单的‘for’循环就可以完成全部工作,每次迭代会向ul元素增加一个li元素。
"""
def header(header_text, header_level=2):
return('<h' + str(header_level) + '>' + header_text +
'</h' + str(header_level) + '>')
"""
创建并返回一个HTML标题标记(H1、H2、H3等),默认为2级标题。
‘header_text’参数是必要的。
"""
def para(para_text):
return('<p>' + para_text + '</p>')
"""
用HTML段落标记包围一个文本段(一个字符串)。好像有些没必要,是不是?
"""
这可以用start_response()控制:
>>> start_response()
'Content-type: text/html\n\n'
>>>start_response("text/plain")
'Content-type: text/plain\n\n'
>>> start_response('application/json')
'Content-type: application/json\n\n'
include_header()函数生成一个Web页面的开始部分。
>>> include_header("Welcome to myhome on the wed")
'<html>\n<head>\n<title>Welcometo my home on the wed</title>\n<link type="text/css"rel="stylesheet" href="/coach.css"/>\n</head>\n<body>\n<h1>Welcome to my home on the wed</h1>\n'
include_footer()函数会生成一个Web页面末尾的HTML,并提供链接(如果已经提供一个链接字典)。倘若字典为空,就不包含链接HTML:
>>>include_footer({'Home':'/index.html','Select':'/cgi-bin/select.py'})
'<p>\n<ahref="/index.html">Home</a> <ahref="/cgi-bin/select.py">Select</a> \n</p>\n</body>\n</html>\n'
>>> include_footer({})
'<p>\n\n</p>\n</body>\n</html>\n'
strat_form()和end_form()函数会建立一个HTML表单,并用参数(如果提供参数)来调整所生成的HTML的内容:
>>>start_form('/cgi-bin/process-athlete.py')
'<formaction="/cgi-bin/process-athlete.py" method="POST">'
>>> end_form()
'<p></p><input type=submitvalue="Submit"></form>'
HTML单选钮很容易创建,可以用radio_button()函数来创建:
>>> for fab in['John','Paul','George','Ringo']:
radio_button(fab,fab)
用u_list()函数可以轻松地创建无序列表:
>>> u_list(['Life of Brian','Holy Gail'])
'<ul><li>Life ofBrian</li><li>Holy Gail</li></ul>'
header()函数允许快速建立选定级别的HTML标题(默认级别2):
>>> header("Welcome to my home onthe web")
'<h2>Welcome to my home on theweb</h2>'
>>> header("This is asub-sub-sub-sub heading",5)
'<h5>This is a sub-sub-sub-subheading</h5>'
para()函数会把一个文本块包围在HTML段落标记中间:
>>> para("Was it worth the wait?wehope it was...")
'<p>Was it worth the wait?we hope itwas...</p>'
Webapp
模块:simple_httpd
from http.serverimport HTTPServer, CGIHTTPRequestHandler #导入HTTP服务器和CGI模块
port = 8080 #指定一个端口
httpd = HTTPServer(('', port), CGIHTTPRequestHandler) #创建一个HTTP服务器
print("Starting simple_httpd on port: " +str(httpd.server_port)) #显示友好信息
httpd.serve_forever() #启动服务器
模块:generate_list
import cgitb
cgitb.enable() #启动Python的CGI跟踪技术
import athletemodel
import yate
import glob #用“glob”模块可以向操作系统查询一个文件名列表"data/*.txt"
data_files=glob.glob("data/*.txt")
athletes=athletemodel.put_to_store(data_files) #利用函数储存数据
print(yate.start_response()) #总是从一个comtent-type行开始
print(yate.include_header("Coach Kelly's List ofAthletes")) #开始生成一个web页面,提供一个合适的标题
print(yate.start_form("generate_timing_data.py"))#开始生成表单,提供要链接的服务器端程序的名
print(yate.para("Select an athlete from the listto work with:")) #这是一个段落,告诉你的用户要做什么
for each_athlete in athletes: #为各个选手分别生成一个单选钮
print(yate.radio_button("which_athlete",athletes[each_athlete].name)) #访问属性name
print(yate.end_form("Select")) #生成表单的最后创建一个定制的“提交”按钮
print(yate.include_footer({"Home":"/index.html"}))#在生成的HTML页面最下面增加一个链接,指向主页
模块:generate_timing_data
import cgitb
cgitb.enable()
import cgi
import athletemodel
import yate
athletes=athletemodel.get_from_store() #从模型取得数据
#你在处理哪个选手的数据
form_data=cgi.FieldStorage()
athlete_name=form_data['which_athlete'].value #访问类属性value
print(yate.start_response())
print(yate.include_header("Coach Kelly's Timing Data"))
print(yate.header("Athlete:"+athlete_name+", DOB: "+
athletes[athlete_name].dob+".")) #获取选手的名字和出生日期
print(yate.para("The top times for this athlete are: "))
print(yate.u_list(athletes[athlete_name].top3))#将前3个时间转换为一个无序HTML列表
print(yate.include_footer({"Home":"/index.html",
"Selectanother athlete":"generate_list.py"}))
#这个web页面的最下面由两个链接