本身動手寫一個web框架,由於我是菜鳥,對於python的一些內建函數不是清楚,因此在寫這篇文章以前須要一些python和WSGI的預備知識,這是一系列文章。這一篇只實現瞭如何處理url。html
參考這篇文章:http://www.cnblogs.com/russellluo/p/3338616.htmlpython
web框架主要是實現web服務器和web應用之間的交互。底層的網絡協議主要有web服務器完成。譬如監聽端口,填充報文等等。web
迭代器爲類序列對象提供了類序列的接口,也就是說類序列對象能夠經過迭代器像序列同樣進行迭代。說簡單一點就是遍歷對象。若是想讓類是可迭代的,那麼就必須實現__iter__和next()。數據庫
只要在類定義的時候實現了__call__方法,那麼該類的對象就是可調有的,便可以將對象當作函數來使用。這裏只用明白什麼是__call__函數便可,由於WSGI規範中用要求。django
關於WSGI的介紹能夠點擊http://webpython.codepoint.net,有很詳細的介紹。這裏只說明一下大概。WSGI接口是用可調用的對象實現的:一個函數,一個方法或者一個可調用的實例。下面是一個實例,註釋寫的很詳細:服務器
# 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]
簡單來講就是根據接收的參數來返回相應的結果。網絡
我以前用過django寫過一個很簡單的博客,目前放在SAE上,很久沒更新了。網址:http://3.mrzysv5.sinaapp.com。一個web框架最基本的要求就是簡化用戶的代碼量。因此在django中,我只須要寫view、model和url配置文件。下面是我用django時寫的一個處理視圖的函數:app
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})
須要我完成的就是操做數據庫,返回相應的資源。因此我要編寫的web框架就要儘量的封裝一些底層操做,留給用戶一些可用的接口。根據個人觀察,web框架的處理過程大體以下:框架
一個WSGI基類,主要有如下的功能:函數
import re class 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' % args urls = [ ('/','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()
上面的代碼是否是很簡介了,只須要定義函數便可。