国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Python學(xué)習(xí)-編寫(xiě)一個(gè)簡(jiǎn)單的web框架(一)

2019-11-14 17:29:54
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

自己動(dòng)手寫(xiě)一個(gè)web框架,因?yàn)槲沂遣锁B(niǎo),對(duì)于python的一些內(nèi)建函數(shù)不是清楚,所以在寫(xiě)這篇文章之前需要一些python和WSGI的預(yù)備知識(shí),這是一系列文章。這一篇只實(shí)現(xiàn)了如何處理url。

參考這篇文章:http://m.survivalescaperooms.com/russellluo/p/3338616.html

預(yù)備知識(shí)

web框架主要是實(shí)現(xiàn)web服務(wù)器和web應(yīng)用之間的交互。底層的網(wǎng)絡(luò)協(xié)議主要有web服務(wù)器完成。譬如監(jiān)聽(tīng)端口,填充報(bào)文等等。

Python內(nèi)建函數(shù)__iter__和__call__和WSGI

迭代器iterator

迭代器為類序列對(duì)象提供了類序列的接口,也就是說(shuō)類序列對(duì)象可以通過(guò)迭代器像序列一樣進(jìn)行迭代。說(shuō)簡(jiǎn)單一點(diǎn)就是遍歷對(duì)象。如果想讓類是可迭代的,那么就必須實(shí)現(xiàn)__iter__和next()。

__call__

只要在類定義的時(shí)候?qū)崿F(xiàn)了__call__方法,那么該類的對(duì)象就是可調(diào)有的,即可以將對(duì)象當(dāng)做函數(shù)來(lái)使用。這里只用明白什么是__call__函數(shù)即可,因?yàn)閃SGI規(guī)范中用要求。

WSGI

關(guān)于WSGI的介紹可以點(diǎn)擊http://webpython.codepoint.net,有很詳細(xì)的介紹。這里只說(shuō)明一下大概。WSGI接口是用可調(diào)用的對(duì)象實(shí)現(xiàn)的:一個(gè)函數(shù),一個(gè)方法或者一個(gè)可調(diào)用的實(shí)例。下面是一個(gè)實(shí)例,注釋寫(xiě)的很詳細(xì):

# This is our application object. It could have any name,# except when using mod_wsgi where it must be "application"def application( # It accepts two arguments:      # environ points to a dictionary containing CGI like environment variables      # which is filled by the server for each received request from the client      environ,      # start_response is a callback function supplied by the server      # which will be used to send the HTTP status and headers to the server      start_response):   # build the response body possibly using the environ dictionary   response_body = 'The request method was %s' % environ['REQUEST_METHOD']   # HTTP response code and message   status = '200 OK'   # These are HTTP headers expected by the client.   # They must be wrapped as a list of tupled pairs:   # [(Header name, Header value)].   response_headers = [('Content-Type', 'text/plain'),                       ('Content-Length', str(len(response_body)))]   # Send them to the server using the supplied function   start_response(status, response_headers)   # Return the response body.   # Notice it is wrapped in a list although it could be any iterable.   return [response_body]

 簡(jiǎn)單來(lái)說(shuō)就是根據(jù)接收的參數(shù)來(lái)返回相應(yīng)的結(jié)果。

設(shè)計(jì)web框架

我之前用過(guò)django寫(xiě)過(guò)一個(gè)很簡(jiǎn)單的博客,目前放在SAE上,好久沒(méi)更新了。網(wǎng)址:http://3.mrzysv5.sinaapp.com。一個(gè)web框架最基本的要求就是簡(jiǎn)化用戶的代碼量。所以在django中,我只需要寫(xiě)view、model和url配置文件。下面是我用django時(shí)寫(xiě)的一個(gè)處理視圖的函數(shù):

def blog_list(request):    blogs = Article.objects.all().order_by('-publish_date')    blog_num = Article.objects.count()    return render_to_response('index.html', {"blogs": blogs,"blog_num":blog_num}, context_instance=RequestContext(request))def blog_detail(request):    bid = request.GET.get('id','')    blog = Article.objects.get(id=bid)    return render_to_response('blog.html',{'blog':blog})

 需要我完成的就是操作數(shù)據(jù)庫(kù),返回相應(yīng)的資源。所以我要編寫(xiě)的web框架就要盡可能的封裝一些底層操作,留給用戶一些可用的接口。根據(jù)我的觀察,web框架的處理過(guò)程大致如下:

  1. 一個(gè)WSGI應(yīng)用的基類初始化時(shí)傳入配置好的url文件
  2. 用戶寫(xiě)好處理方法,基類根據(jù)url調(diào)用方法
  3. 返回給客戶端視圖

一個(gè)WSGI基類,主要有以下的功能:

  • 處理environ參數(shù)
  • 根據(jù)url得到方法或者類名,并執(zhí)行后返回
import reclass WSGIapp:    headers = []    def __init__(self,urls=()):        self.urls = urls        self.status = '200 OK'    def __call__(self,environ,start_response):        x = self.mapping_urls(environ)        PRint x        start_response(self.status,self.headers)        if isinstance(x,str):            return iter([x])        else:            return iter(x)    def mapping_urls(self,environ):        path = environ['PATH_INFO']        for pattern,name in self.urls:            m = re.match('^'+pattern+'$',path)            if m:                args = m.groups()                func = globals()[name]                return func(*args)        return self.notfound()    def notfound(self):        self.status = '404 Not Found'        self.headers = [('Content-Type','text/plain')]        return '404 Not Found/n'    @classmethod    def header(cls,name,value):        cls.headers.append((name,value))def GET_index(*args):    WSGIapp.header('Content-Type','text/plain')    return 'Welcome!/n'def GET_hello(*args):    WSGIapp.header('Content-Type','text/plain')    return 'Hello %s!/n' % argsurls = [    ('/','GET_index'),    ('/hello/(.*)','GET_hello')    ]wsgiapp = WSGIapp(urls)if __name__ == '__main__':    from wsgiref.simple_server import make_server    httpd = make_server('',8000,wsgiapp)    print 'server starting...'    httpd.serve_forever()

 上面的代碼是不是很簡(jiǎn)介了,只需要定義函數(shù)即可。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 土默特右旗| 师宗县| 永嘉县| 潞西市| 麦盖提县| 青冈县| 阳原县| 东乡县| 定襄县| 交城县| 溧水县| 海门市| 八宿县| 黔西县| 瑞金市| 徐汇区| 和平区| 保靖县| 和政县| 江陵县| 大港区| 上蔡县| 新民市| 瑞安市| 常德市| 景泰县| 滁州市| 大同县| 普陀区| 九台市| 辽中县| 合作市| 鹤山市| 海盐县| 德令哈市| 安远县| 郧西县| 盘山县| 文水县| 新晃| 玉龙|