在上一篇日志中已经讨论和实现了根据url执行相应应用,在我阅读了bottle.py官方文档后,按照bottle的设计重写一遍,主要借鉴大牛们的设计思想。

一个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()

这样,一个简易的web框架的雏形就实现了,如果对装饰器中的路径加入正则表达式,那么就可以很轻松的应对URL了。下一篇日志就是加入模板引擎jinja2了。

最新文章

  1. Mysql 中文乱码(Navicat for MySQL)
  2. 为什么不能在init和dealloc函数中使用accessor方法
  3. ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(3)修改资料、修改密码
  4. LoadRunner --HTML/URL录制方式的选择规则
  5. bzoj 3743
  6. oracle不能删除,查看引用的外键
  7. MSTest、NUnit、xUnit.net 属性和断言对照表
  8. 【读书笔记《Android游戏编程之从零开始》】1.Android 平台简介与环境搭建
  9. scan design rules
  10. phpcms v9 企业黄页系统发布没有表单出现的解决方案
  11. C#解决MDI窗体闪屏的方法
  12. Yii地址美化(nginx环境)
  13. Http远程调用服务
  14. vue 入门第一课
  15. SVN使用基础
  16. zzcms8.2#任意用户密码重置#del.php时间盲注#复现
  17. Linux设备树(五 根节点)
  18. Vue 中是如何解析 template 字符串为 VNode 的?
  19. Cannot set property &#39;onclick&#39; of null报错
  20. C# abstract virtual override new finally java final finalize

热门文章

  1. VM虚拟机下在LINUX上安装ORACLE 11G单实例数据库
  2. Java 8:不要再用循环了
  3. cf 702B
  4. dede 如何去除[field:title/]里面出现的b标签
  5. 【转】eclipse使用git提交到osc
  6. winfrom 底层类 验证码 分类: C# 2014-12-17 11:18 258人阅读 评论(0) 收藏
  7. iOS 自动布局总结
  8. css考核点整理(三)-css选择器的使用
  9. 第九篇:python高级之操作数据库
  10. dede 最近一天发布的文章标题前加hot