代码地址:https://files.cnblogs.com/files/ceshixuexi/HeadFristPython.zip

一般以MVC模式开发

M:模型,存储web应用的代码

V:视图,格式化和显示web应用用户界面的代码

C:控制器,将web应用“粘合”在一起并提供业务逻辑的代码

cgi-bin目录下:

 

1、athletelist.py:

 1 class AthleteList(list):
 2 
 3     def __init__(self, a_name, a_dob=None, a_times=[]):
 4         list.__init__([])
 5         self.name = a_name
 6         self.dob = a_dob
 7         self.extend(a_times)
 8 
 9     @staticmethod  # 静态方法
10     def sanitize(time_string):
11         if \'-\' in time_string:
12             splitter = \'-\'
13         elif \':\' in time_string:
14             splitter = \':\'
15         else:
16             return(time_string)
17         (mins, secs) = time_string.split(splitter)
18         return(mins + \'.\' + secs)
19 
20     @property # 这个修饰符可以将方法看做类属性
21     def top3(self):
22         return(sorted(set([self.sanitize(t) for t in self]))[0:3])

 

2、athletemodel.py

 1 import pickle
 2 
 3 from athletelist import AthleteList
 4 
 5 def get_coach_data(filename):
 6     try:
 7         with open(filename) as f:
 8             data = f.readline()
 9         templ = data.strip().split(\',\')
10         return(AthleteList(templ.pop(0), templ.pop(0), templ))
11     except IOError as ioerr:
12         print(\'File error (get_coach_data): \' + str(ioerr))
13         return(None)
14 
15 def put_to_store(files_list):
16     all_athletes = {}
17     for each_file in files_list:
18         ath = get_coach_data(each_file)
19         all_athletes[ath.name] = ath
20     try:
21         with open(\'athletes.pickle\', \'wb\') as athf:
22             pickle.dump(all_athletes, athf)
23     except IOError as ioerr:
24         print(\'File error (put_and_store): \' + str(ioerr))
25     return(all_athletes)
26 
27 def get_from_store():
28     all_athletes = {}
29     try:
30         with open(\'athletes.pickle\', \'rb\') as athf:
31             all_athletes = pickle.load(athf)
32     except IOError as ioerr:
33         print(\'File error (get_from_store): \' + str(ioerr))
34     return(all_athletes)

 

3、generate_list.py

 

 1 import glob
 2 import athletemodel
 3 import yate
 4 
 5 
 6 data_files = glob.glob(\'data/*.txt\')
 7 athletes = athletemodel.put_to_store(data_files)
 8 
 9 print(yate.start_response())
10 print(yate.include_header("Coach Kelly\'s List of Athletes"))
11 print(yate.start_form("generate_timing_data.py"))
12 print(yate.para(\'Select an athlete from the list to work with:\'))
13 for each_athlete in athletes:
14     print(yate.radio_button("which_athlete", athletes[each_athlete].name))
15 print(yate.end_form("Select"))
16 print(yate.include_footer({\'Home\': \'/index.html\'}))

 

 

4、yate.py

 1 from string import Template
 2 # 从标准库string中导入Temlate类
 3 
 4 
 5 def start_response(resp="text/html"):
 6     return(\'Content-type: \' + resp + \'\n\n\')
 7     # 这个函数需要一个可选的字符串作为参数,用它来创建一个CGI“content-type:”行,参数缺省值为“text/html”
 8 
 9 def include_header(the_title):
10     with open(\'templates/header.html\') as headf:
11         # 打开模板文件,读入文件,换入所提供的标题
12         head_text = headf.read()
13     header = Template(head_text)
14     return(header.substitute(title=the_title))
15     # 这个函数需要一个字符串作为参数,用在html页面最前面的标题中。页面本身存储在一个单独的文件“templates/header.html”
16     # 可以根据需要替换标题
17 
18 def include_footer(the_links):
19     with open(\'templates/footer.html\') as footf:
20         foot_text = footf.read()
21     link_string = \'\'
22     # 换入链接字典
23     for key in the_links:
24         # 将链接字典转换为一个字符串,然后换入模板
25         link_string += \'<a href="\' + the_links[key] + \'">\' + key + \'</a>&nbsp;&nbsp;&nbsp;&nbsp;\'
26     footer = Template(foot_text)
27     return(footer.substitute(links=link_string))
28     # 与include_header函数一样,这个函数使用一个字符串作为参数,来创建htm页面的尾部
29     # 页面本身存储在"template/footer"中,参数用于动态地创建一组html链接标记。从这些标记看,参数应该是一个字典
30 
31 def start_form(the_url, form_type="POST"): # 这一般是post或者get
32     return(\'<form action="\' + the_url + \'" method="\' + form_type + \'">\')
33     # 这个函数返回表单最前面的html,允许调用者指定url,还可以指定所要使用的方法
34 
35 def end_form(submit_msg="Submit"):
36     return(\'<p></p><input type=submit value="\' + submit_msg + \'"></form>\')
37     # 这个函数返回的表单末尾的html标记,同时还允许调用着制定表单“submit”按钮的文本
38 
39 def radio_button(rb_name, rb_value):
40     return(\'<input type="radio" name="\' + rb_name +
41                              \'" value="\' + rb_value + \'"> \' + rb_value + \'<br />\')
42     # 给定一个单选按钮名和值,创建一个html单选按钮(通常包括在一个html表单中)。注意:2个参数都是必要的
43 
44 def u_list(items):
45     u_string = \'<ul>\'
46     for item in items:
47         # 一个简单的for循环就可以达到目的
48         u_string += \'<li>\' + item + \'</li>\'
49     u_string += \'</ul>\'
50     return(u_string)
51     # 给定一个项列表,这个函数会把该列表转换为一个html无序列表。一个简单的for循环就可以达到目的
52 
53 def header(header_text, header_level=2):
54     return(\'<h\' + str(header_level) + \'>\' + header_text +
55            \'</h\' + str(header_level) + \'>\')
56     # 创建并返回一个html标题标记(h1,h2,h3等),默认为h2级标题。“header_text”参数是必要的
57 
58 def para(para_text):
59     return(\'<p>\' + para_text + \'</p>\') 
60     # 文本

 

 

5、generate_timing_data.py

 1 #! /usr/local/bin/python3
 2 
 3 import cgi
 4 
 5 import cgitb
 6 cgitb.enable()
 7 #这两行代码启用python的CGI跟踪技术
 8 
 9 import athletemodel
10 import yate
11 
12 
13 
14 
15 
16 athletes = athletemodel.get_from_store()
17 # 从模型获得数据
18 
19 form_data = cgi.FieldStorage()
20 #所有表单数据,并放到一个字典中
21 
22 athlete_name =form_data[\'which_athlete\'].value
23 #从表单数据中访问一个指定的数据
24 
25 print(yate.start_response())
26 print(yate.include_header("Coach Kelly\'s Timing Data"))
27 print(yate.header("Athlete: " + athlete_name + ", DOB: " +
28                       athletes[athlete_name].dob + "."))
29 print(yate.para("The top times for this athlete are:"))
30 print(yate.u_list(athletes[athlete_name].top3))
31 print(yate.include_footer({\'Home\':"/index.html",
32                            "Select anthor athlete:":"generate_list.py"}))

 

http.py

from http.server import HTTPServer, CGIHTTPRequestHandler

port = 8002

httpd = HTTPServer((\'\', port), CGIHTTPRequestHandler)
print("Starting simple_httpd on port: " + str(httpd.server_port))
httpd.serve_forever()

 

版权声明:本文为ceshixuexi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ceshixuexi/p/8337740.html