《深入浅出Python》6,7 定制数据对象,web开发

本文介绍使用Python进行Web开发的过程,包括处理数据规范化、去重、排序等操作,通过类实现数据管理和展示,以及如何构建Web服务器和生成动态网页。

要点
  1. pop(0) :调用将删除并返回列表最前面的数据项。
  2. “映射”,“散列”,“关联数组”,实际上就是指“字典”
  3. 创建字典两种方法
    • cheese = {}
    • paline = dict()
  4. set的作用:set会自动去掉重复的元素.dict的作用是建立一组 key 和一组 value 的映射关系,dict的key是不能重复的。有的时候,我们只想要 dict 的 key,不关心 key 对应的 value,目的就是保证这个集合的元素不会重复,这时,set就派上用场了。set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像。创建 set 的方式是调用 set() 并传入一个 list,list的元素将作为set的元素。
铺垫
"""
现有几个数字,记录运动员的速度。你需要做的有
1.处理数据为规范数字
2.去重,排序
3.寻找某人前3的成绩是什么
4.有新加入的时间
"""
#创建一个函数,用来使数字规范化
def sanitize(time_string):
	if '-' in time_string:
		splitter = '-'
	elif ':' in time_string:
		splitter = ':'
	else:
		return(time_string)
	(mins,secs)=time_string.split(splitter)
	return(mins+'.'+secs)

#创建一个类,类的作用就是用来处理传入的文件,去重,排序,找到前三的成绩
class Athelete():
	#先创建一个初始化函数
	def __init__(self,a_name,a_bir=None,a_times=[]):
		self.name = a_name
		self.bir = a_bir
		self.times = a_times

	#找到top3的成绩,先一个一个取,先规范化,再去重,再排序
	def top3(self):
		return(sorted(set({sanitize(i) for i in self.times}))[0:3])

	#新加入的时间,将此时间加入到时间列表里
	def add_time(self,time_value):
		self.times.append(time_value)

	def add_times(self,time_list):
		self.times.extend(time_list)

#创建一个函数,用来处理传入的文件,文件要以“,”逗号进行分隔,要去空。
def get_coach_date(file_name):
	try:
		with open (file_name) as f:
			data = f.readline()
			tmp = data.strip().split(',')
			return(Athelete(tmp.pop(0),tmp.pop(0),tmp))

	except IOError as ioerr:
		print('File error:'+str(ioerr))
		return(None)

#调用验证
james = get_coach_date('james2.txt')
print(james.name,"'s faster times are:"+ str(james.top3()))


viva = Athelete('VIVA')
viva.add_times(['2.22','2-23','2:24'])
print(viva.top3())

athletemodel.py


# atheletelist是刚刚编写号的模块,是一个.py的文件,放在同一个文件夹下
import pickle
from atheletelist import Atheletelist
def get_coach_date(filename):
	try:
		with open(filename) as f:
			data = f.readline()
		tmp = data.strip().split('.')
		return(Atheletelist(tmp.pop(0),tmp.pop(0),tmp))
	except IOError as irror:
		print("Filr Error"+str(irror))
		return(None)

def put_to_store(file_list):
	all_athletes={}
	for eache_file in file_list:
		ath = get_coach_date(eache_file) #将各个文件转换为一个AthleteList对象实例,并把选手的数据增加到字典
		all_athletes[ath.name] = ath #每个选手的名字作为字典的键,值是AthleteList对象实例
	try:
		with open('athletes.pickle','wb') as athf:
			pickle.dump(all_athletes,athf) #将整个AthleteList增加到一个pickle中
	except IOError as ioerr:
		print('File error(put_to_store):' +str(ioerr))
	return(all_athletes)

def get_from_store():
	all_athletes = {}
	try:
		with open('athletes.pickle','rb') as athf:
			all_athletes = pickle.load(athf) #将pickle读入字典
	except IOError as ioerr:
		print('File error(get_from_store):' +str(ioerr))
	return(all_athletes)

generate_list.py

import athletemodel
import yate
import glob

data_files = glob.glob('data/*.txt')
athletes = athletemodel.put_to_store(data_files)

print(yate.start_response())
print(yate.include_header("Coach Kelly's List of Athletes"))
print(yate.start_form("generate_timing_data.py"))
print(yate.para("Select an athlete from the list to work with:"))

for each_athlete in athletes:
    print(yate.radio_button("which athlete",athletes[each_athlete].name))
print(yate.end_form("Select"))

print(yate.include_fotter({"Home":"/index.html"}))
                                                                                                                                                                  

以上是做实验时写的东西
正式web数据在书中有说,可以去深入浅出的官网进行下载
链接: http://python.itcarlow.ie/resources.html
解压后的文件夹
在这里插入图片描述

在这里插入图片描述

文件夹下的具体文件内容
在这里插入图片描述

开发内容

cgi-bin文件夹中
athletelist.py

#定义一个类
class AthleteList(list):
#先创建一个初始化函数
    def __init__(self, a_name, a_dob=None, a_times=[]):
        list.__init__([])
        self.name = a_name
        self.dob = a_dob
        self.extend(a_times)
#规范化传入的时间内容
    @staticmethod
    def sanitize(time_string):
        if '-' in time_string:
            splitter = '-'
        elif ':' in time_string:
            splitter = ':'
        else:
            return(time_string)
        (mins, secs) = time_string.split(splitter)
        return(mins + '.' + secs)
#@property 是一个修饰符,可以使类表现的像是一个类属性
#找出前三的时间
    @property
    def top3(self):
        return(sorted(set([self.sanitize(t) for t in self]))[0:3])
#清空内容
    @property
    def clean_data(self):
        return(sorted(set([self.sanitize(t) for t in self])))

athletemodel.py


import pickle

from athletelist import AthleteList

def get_coach_data(filename):
    try:
        with open(filename) as f:
            data = f.readline()
        templ = data.strip().split(',')
        return(AthleteList(templ.pop(0), templ.pop(0), templ))
    except IOError as ioerr:
        print('File error (get_coach_data): ' + str(ioerr))
        return(None)

def put_to_store(files_list):
    all_athletes = {}
    for each_file in files_list:
        ath = get_coach_data(each_file)
        all_athletes[ath.name] = ath
    try:
        with open('athletes.pickle', 'wb') as athf:
            pickle.dump(all_athletes, athf)
    except IOError as ioerr:
        print('File error (put_and_store): ' + str(ioerr))
    return(all_athletes)

def get_from_store():
    all_athletes = {}
    try:
        with open('athletes.pickle', 'rb') as athf:
            all_athletes = pickle.load(athf)
    except IOError as ioerr:
        print('File error (get_from_store): ' + str(ioerr))
    return(all_athletes)

generate_list.py

#导入之前创建的模块
import athletemodel
import yate
#利用glob模块可以在操作系统中查询文件名
import glob

data_files = glob.glob('data/*.txt')
athletes = athletemodel.put_to_store(data_files)

print(yate.start_response())
#开始生成web页面,提供一个合适的标题
print(yate.include_header("Coach Kelly's List of Athletes"))
#开始生成表单,提供要链接的服务器端程序名
print(yate.start_form("generate_timing_data.py"))
print(yate.para("Select an athlete from the list to work with:"))
#为各个选手分别生成一个单选钮
for each_athlete in athletes:
  print(yate.radio_button("which_athlete",athletes[each_athlete].name))
#创建一个提交按钮
print(yate.end_form("Select"))

print(yate.include_fotter({"Home":"/index.html"}))

generate_timing_data.py

#导入要用的库和模块
#导入Python的CGI模块来访问表单数据,这也是标准库中的一个模块
import cgi
#Python的标准库提供了一个CGI跟踪模块(名为DGITB),启用这个模块时,会在web浏览器上显示详细的错误信息。这些信息可以帮你找出CGI哪里出了问题。改正错误并且CGI正常工作后,再关闭CGI跟踪
import cgitb
cgitb.enable()
import athletemodel
import yate


#从模型得到数据
#调用athletemodel中的方法,获取pickle中的数据
athletes = athletemodel.get_from_store()

#访问你所选择的表单,德大表单数据
#再得到表单数据中单选按钮选择的数据"which_athlete"
form_data=cgi.FieldStorage()
athlete_name = form_data['which_athlete'].value

#生成所需要的HTML页面
#获取选手的名字和出生日期
print(yate.start_response())
print(yate.include_header("Coach Kelly's Timing Data"))
print(yate.header("Athlete"+athlete_name +",Dob:"+athletes[athlete_name].dob+"."))

#将前三个时间转换为一个无序HTML列表
print(yate.para("The top times for this athlete are:"))

#这个web页面的最下面有两个链接
#这里把top3看成一个类的属性,所以不写成top3()的形式
print(yate.u_list(athletes[athlete_name].top3))
print(yate.include_footer({"Home":"/index.html","Select another athlete":"generate_list.py"}))

yate.py这是一个前端展现,在MVC中是View

#从string模块中导入Template类,这个类的可以进行简单的字符串替换
from string import Template

def start_response(resp="text/html"):
    return('Content-type: ' + resp + '\n\n')

def include_header(the_title):
    with open('templates/header.html') as headf:
        head_text = headf.read()
    header = Template(head_text)
    return(header.substitute(title=the_title))

def include_footer(the_links):
    with open('templates/footer.html') as footf:
        foot_text = footf.read()
    link_string = ''
    for key in the_links:
        link_string += '<a href="' + the_links[key] + '">' + key + '</a>&nbsp;&nbsp;&nbsp;&nbsp;'
    footer = Template(foot_text)
    return(footer.substitute(links=link_string))

def start_form(the_url, form_type="POST"):
    return('<form action="' + the_url + '" method="' + form_type + '">')

def end_form(submit_msg="Submit"):
    return('<p></p><input type=submit value="' + submit_msg + '"></form>')

def radio_button(rb_name, rb_value):
    return('<input type="radio" name="' + rb_name +
                             '" value="' + rb_value + '"> ' + rb_value + '<br />')

def u_list(items):
    u_string = '<ul>'
    for item in items:
        u_string += '<li>' + item + '</li>'
    u_string += '</ul>'
    return(u_string)

def header(header_text, header_level=2):
    return('<h' + str(header_level) + '>' + header_text +
           '</h' + str(header_level) + '>')

def para(para_text):
    return('<p>' + para_text + '</p>') 
最后生成界面

用Python构建一个Web服务器必须有以下这5行代码
通用网关接口(Comman Gateway Interface,CGI)是一个Internet标准,允许Web服务器运行一个服务器端程序,成为CGI脚本。
一般地,CGI脚本都放在一个名为cgi-bin的特殊文件夹下,这样Web服务器才能知道在哪里查找CGI脚本。
在我们的下载文件里有一个simplehttpd.py的文件,它提供了一个支持CGI的Web服务器。
Python提供了它自己的Web服务器,这个Web服务器包含在http.server库模块中。

#导入HTTP服务器和CGI模块
from http.server import HTTPServer, CGIHTTPRequestHandler

#指定一个端口
port = 8080

#创建一个HTTP服务器
httpd = HTTPServer(('', port), CGIHTTPRequestHandler)
#显示一个友好的信息,并启动服务器
print("Starting simple_httpd on port: " + str(httpd.server_port))
httpd.serve_forever()
--------------------- 
作者:星际丶牛仔 
来源:优快云 
原文:https://blog.csdn.net/ahaha413525642/article/details/76407412 
版权声明:本文为博主原创文章,转载请附上博文链接!
  1. 主页
    在这里插入图片描述

  2. 点击timing data 转到 generate_list.py 生成的界面中
    在这里插入图片描述

  3. 选择任意选手,进入到 generate_timing_data.py 生成的页面中
    在这里插入图片描述

Tips:
  1. @property 是一个修饰符,可以使类表现的像是一个类属性
  2. cgi.FieldStorage()访问作为Web请求一部分发送给Web服务器的数据,数据作为一个Python字典。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值