在上一篇日誌中已經討論和實現了根據url執行相應應用,在我閱讀了bottle.py官方文檔後,按照bottle的設計重寫一遍,主要借鑑大牛們的設計思想。html
來看看bottle是如何使用的,代碼來自http://www.bottlepy.org/docs/0.12/index.html:python
from bottle import route, run, template @route('/hello/<name>') def index(name): return template('<b>Hello {{name}}</b>!', name=name) run(host='localhost', port=8080)
很顯然,bottle是使用裝飾器來路由的。根據bottle的設計,我來寫一個簡單的框架。web
裝飾器,顧名思義就是包裝一個函數。在不改變函數的同時,動態的給函數增長功能。這裏不在探討更多的細節。正則表達式
根據WSGI的定義,一個WSGI應用必需要是可調用的。因此下面是一個WSGI應用的大體框架:app
class WSGIapp(object): def __init__(self): pass def route(self,path=None): pass def __call__(self,environ,start_response): return self.wsgi(environ,start_response) def wsgi(self,environ,start_response): pass
其中,route方法就是來保存url->target的。這裏爲了方便,將url->target保存在字典中:框架
def route(self,path=None): def decorator(func): self.routes[path] = func return func return decorator
這裏return func註釋掉也能夠,求大神解釋一下啊!!函數
而後就是實現WSGIapp的每一個方法:url
class WSGIapp(object): def __init__(self): self.routes = {} def route(self,path=None): def decorator(func): self.routes[path] = func return func return decorator def __call__(self,environ,start_response): print 'call' return self.wsgi(environ,start_response) def wsgi(self,environ,start_response): path = environ['PATH_INFO'] print path if path in self.routes: status = '200 OK' response_headers = [('Content-Type','text/plain')] start_response(status,response_headers) print self.routes[path]() return self.routes[path]() else: status = '404 Not Found' response_headers = [('Content-Type','text/plain')] start_response(status,response_headers) return '404 Not Found!' app = WSGIapp() @app.route('/') def index(): return ['This is index'] @app.route('/hello') def hello(): return ['hello'] from wsgiref.simple_server import make_server httpd = make_server('',8000,app) print 'start....' httpd.serve_forever()
這樣,一個簡易的web框架的雛形就實現了,若是對裝飾器中的路徑加入正則表達式,那麼就能夠很輕鬆的應對URL了。下一篇日誌就是加入模板引擎jinja2了。spa