接着上面讲,在head first这本书当中,采用的例子是人物问答的形式,你首先要想想自己的webapp看上去是什么样子,另外在web浏览器上是什么样子,这有助于帮助你明白你的webapp需要做些什么。

这里按照书上的例子来,kelly教练希望能够有一个漂亮友好的主页,两个小朋友希望能够轻松得到他们的运动数据(这是书上一个贯彻全书的例子),另外这些数据应该漂亮的呈现给用户。

这样我们就可以简单的对我们的web进行设计:一个欢迎页面,一个选择选手的页面,以及一个显示时间的页面。

既然已经明白你的构建,那么我们下一个需要思考的问题就是如何实现我们的设计?用什么方法?问不同的人也许你会得到不同的回答,但是一般来讲,我们都会遵循mvc模式,即model_view_controller(模型_视图_控制器)模式,这有助于将web设计分成易于管理的功能模块。这样,当需要改变的时候,我们可以很轻松的实现扩展,同时,作为一个团队,我们也可以更简单的实现任务的分配,尽管这里我们实现的只是简单的任务,但是这种思想的贯彻对我们将来的team生活是有极大的帮助的!

至于什么是模型,视图,我们在实践中去理解,给出定义。

按照上面的步骤,我们首先是模型部件,书本上首先是为数据建模,而书本上模型给出的定义是存储(以及有时处理)web应用数据的代码。这里web服务器需要存储数据的一个副本,在这里数据就是kelly教练的计时值(来自他的文本文件),启动这个webapp时,我们首先需要把文本文件当中的AthleteList对象实例,存储在一个字典当中,然后保存为一个pickle文件,下面自动把这个功能封装在put_to_store()的新函数当中,暂时我也对pickle这种存在的意义不是很理解,毕竟没有使用过,也不知道它的帮助,但是我们知道它可以作为文件,这就足够了。

当这个webapp运行时,pickle文件中的数据可以作为一个字典供使用,下面把这个数据提取过程封装在get_from_store()函数当中,

import pickle
from athletelist import AthleteList
def get_coach_data(filename):
    try:
        with open(filename) as f:
            data=f.readline()
        temp1=data.strip().split(",")
        return(AthleteList(temp1.pop(0),temp1.pop(0),temp1))
    except IOError as ioerr:
        print('file error: '+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)

而athletelist的代码如下:

#head_first_python
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)
    def top3(self):
        return(sorted(set([sanitize(t) for t in self]))[0:3])
def sanitize(time_string):
    if "-" in time_string:
        splitter="-"
    if ":" in time_string:
        splitter=":"
    else:
        return(time_string)
    (mins,secs)=time_string.split(splitter)
    return(mins+"."+secs)

此时回过头来看这个pickle,虽然还是很陌生,但是我们却可以发现它把变量对象直接存储在pickle文件中,读取时可以直接使用,这就可以方便我们使用而不用再去把值存储在新的变量当中,特别是某些情况下这种操作可能特别繁琐。