如何用Python写一个web框架

 我来答
育知同创教育
2017-12-25 · 百度知道合伙人官方认证企业
育知同创教育
1【专注:Python+人工智能|Java大数据|HTML5培训】 2【免费提供名师直播课堂、公开课及视频教程】 3【地址:北京市昌平区三旗百汇物美大卖场2层,微信公众号:yuzhitc】
向TA提问
展开全部

STEP.1

我们首先得选择基于什么协议来写这种框架。我们可以选择CGI协议,或者是WSGI接口。如果使用CGI,实际上我们只是按着CGI的规范写了一个python程序,然后每次服务器收到请求,就fork一个程序来执行它,然后返回一个http文档,性能比较低下。对于WSGI,而是一个存在于服务器和应用间的接口,在WSGI之前,web应用都是依赖于服务器的,现在流行的python框架都支持WSGI接口。

STEP.2 PEP-333

这一段是PEP-333 所提供的样例代码。

def simple_app(environ, start_response):
"""Simplest possible application object"""
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return ['Hello world!\n']

这里的application被传入了两个值。

  • environ

  • start_response。
    environ是一个字典,保存了http请求的信息。
    start_response是一个函数,发送http响应。她有两个参数status 和 start_headers。

  • status必须是由状态编号和具体信息组成的字符串,必须符合RFC 2616。

  • start_headers是一个(header_name,header_value) 元组的列表元组列表。其中的hearder_name必须是合法的http header字段名。在RFC 2616, Section 4.2中有详细定义。
    当然官方还给出了类的实现。

  •  def __init__(self, environ, start_response):


  •        self.environ = environ


  •        self.start = start_response

  •    def __iter__(self):


  •        status = '200 OK'


  •        response_headers = [('Content-type','text/plain')]


  •        self.start(status, response_headers)


  •        yield "Hello world!\n"

  • 了解了如上信息后,基本上可以开始了。我们就到官方给的代码上进行修改吧。

    STEP.3 将路径链接到函数

    首先我们得把用户请求的路径,链接到函数。我们可以实现一个getPage方法,专门做这件事。我们所拥有的信息,只有environ['PATH_INFO']。

  • urls = [('^/index/$','func_index'),

  •        ('^/comment/$','func_comment'),

  •        ('^/environ/$','get_environ'),

  •        ('^/post/$','post_test')]#urls是提供给app开发者来做链接的。

  •    def getPage(self):

  •        path = self.environ['PATH_INFO']

  •        for pattern in self.urls:

  •            m = re.match(pattern[0],path)#将urls元素的第0项和path进行比对,如果匹配上了,返回函数名

  •            if m:

  •                function = getattr(self,pattern[1])#getattr方法来得到函数

  •                return function()

  •        return '404 not found'#没匹配上任何东西

  • 写到这里之后,每次添加页面,就只需要在urls列表中添加一个元祖就行了。

    STEP.4 获取模版

    既然是写web app,模版肯定是得有的。这里我提供了一种getTemplate方法来做这件事。不过我只提供了变量的替换。

  •    def getTemplate(self,tem_name,rep=0):

  •        #这个函数返回内容,tem_name是文件名字

  •        #参数rep是一个字典,默认为0

  •        f = open('template/'+tem_name)

  •        html = f.read()

  •        if(rep!=0):

  •            for to_replace in rep:

  •                strinfo = re.compile('\{\%\s*'+str(to_replace)+'\s*\%\}')

  •                html = strinfo.sub(rep[to_replace],html)

  •        return html

  • STEP.5 POST数据的处理

    要想获取POST数据,我们得通过environ['wsgi.input']来处理。而他实际上就是系统的标准输入。

  • environ['wsgi.input']        = sys.stdin

  • 知道这点后就很好写了。

  •    def getPost(self):

  •        if(self.environ['REQUEST_METHOD'] == 'POST'):

  •            try:

  •                request_body_size = int(self.environ.get('CONTENT_LENGTH', 0))#读出content_length的值

  •            except:

  •                request_body_size = 0

  •            request_body = self.environ['wsgi.input'].read(request_body_size) #请求的body

  •            post_data = parse_qs(request_body)#parse_qs是cgi提供的方法,帮助我们处理请求

  •            return post_data

  • 数据库的链接

  • import MySQLdb

  • class Model(object):

  •    def __init__(self):

  •            self.host = 'localhost'

  •            self.port = 3306

  •            self.user = 'admin'

  •            self.passwd = 'admin'

  •            self.db = 'xieyi'

  •    def build_connect(self):

  •        self.conn = MySQLdb.connect(

  •            host = self.host,

  •            port = self.port,

  •            user = self.user,

  •            passwd = self.passwd,

  •            db = self.db

  •            )

  •    def exec_ins(self,ins):

  •        cur = self.conn.cursor()

  •        num = cur.execute(ins)

  •        info = {}

  •        if(num>0):

  •            info = cur.fetchmany(num)

  •        cur.close()

  •        self.conn.commit()

  •        return info

  •    def close(self):

  •        self.conn.close()

  • STEP.6 清理工作

    很多配置如果放到代码中,会增加阅读负担。于是把urls,model抽取出来。
    使得配置更加方便。



推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式