Python学习 - 编写一个简单的web框架(二)


一个bottle.py的简单实例
来看看bottle是如何使用的,代码来自http://www.bottlepy.org/docs/0.12/index.html:
 
复制代码
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的设计,我来写一个简单的框架。
 
Python装饰器
装饰器,顾名思义就是包装一个函数。在不改变函数的同时,动态的给函数增加功能。这里不在探讨更多的细节。
 
大致的框架
根据WSGI的定义,一个WSGI应用必须要是可调用的。所以下面是一个WSGI应用的大致框架:
 
 
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的每个方法:
 
复制代码
 
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()

评论关闭