werkzeug实现简单Python web框架(1):MVC模式

Werkzeug是Python的WSGI规范的实用函数库。使用广泛,基于BSD协议。
Flask底层就是使用了Werkzeug。
完整代码:
https://github.com/yangzhezjgs/Light/tree/master/webapp

Python版本:
最好使用Python3,Python2需要修改except HTTPException as e 为except HTTPException , e
总体思想
通过url_map这个字典建立url和处理url的视图函数之间的映射关系。
思路参考Werkzeug给出的官方示例:
https://github.com/pallets/werkzeug/blob/0.12.2/examples/webpylike/webpylike.py

关键点:
add_url_rule方法调用,导致视图类通过调用类方法,返回一个闭包,闭包返回一个视图函数,于是建立了url与视图函数的映射关系。
run_simple启动一个wsgi服务器,self参数调用自身(因为实现__call__ 方法,对象变为可调用对象)

代码

from werkzeug.wrappers import BaseRequest, BaseResponse
from werkzeug.exceptions import HTTPException, MethodNotAllowed, \
     NotImplemented, NotFound
from werkzeug.serving import run_simple

class Request(BaseRequest):
    """Encapsulates a request."""


class Response(BaseResponse):
    """Encapsulates a response."""


class View(object):
    """Baseclass for our views."""
    def __init__(self):
        self.methods_meta = {
            'GET': self.GET,
            'POST': self.POST,
            'PUT': self.PUT,
            'DELETE': self.DELETE,
        }
    def GET(self):
        raise MethodNotAllowed()
    POST = DELETE = PUT = GET

    def HEAD(self):
        return self.GET()
    def dispatch_request(self, request, *args, **options):
        if request.method in self.methods_meta:
            return self.methods_meta[request.method](request, *args, **options)
        else:
            return '<h1>Unknown or unsupported require method</h1>'

    @classmethod
    def get_func(cls):
        def func(*args, **kwargs):
            obj = func.view_class()
            return obj.dispatch_request(*args, **kwargs)
        func.view_class = cls
        return func

class WebApp(object):
    def __init__(self):
        self.url_map = {}

    def __call__(self, environ, start_response):
        try:
            req = Request(environ)
            url = req.path
            view = self.url_map.get(url, None)
            if view:
                response = view(req)
                response = Response(response)
            else:
                response = Response('<h1>404 Source Not Found<h1>', content_type='text/html; charset=UTF-8', status=404)
        except HTTPException as e:
            response = e
        return response(environ, start_response)

    def add_url_rule(self,urls):
         for url in urls:
             self.url_map[url['url']] = url['view'].get_func() 

    def run(self, port=5000, ip='', debug=False):
        run_simple(ip, port, self, use_debugger=debug, use_reloader=True)

使用示例

from webapp import WebApp,View
class Index(View):
    def GET(self,request):
        return "hello world"

class Test(View):
    def GET(self,request):
        return "test"

urls = [
{
    'url':'/',
    'view':Index
},
{
   'url':'/test',
   'view':Test
}
] 


app = WebApp()

app.add_url_rule(urls)

app.run()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值