webpy源码阅读之HelloWorld

使用过Django和web.py,只是一直没有好好深入学习过,Django使用时间比较长,不过Django庞大了点,不适合我这种没耐心的人去学习,所以选择了web.py。 Hello World! 先看下web.py官方cookbook的“Hello World!”例子 import web urls = ("/.*"), "hello") app = web.application(urls, globals()) class hello: def GET(self): return 'Hello, world!' if __name__ == "__main__": app.run() 在例子中可以看到app.run()是启动了服务,而app的是application的一个实例,初始化工作是web.application(urls, globals()),就拿这个做入口,来看下application类的源码吧。 初始化 初始化的流程: 初始化mapping 把_load和_unload变成钩子加入到processors 把Reloader和reload_mapping变成钩子加入到processors 载入main所在模块 init的参数有三个,第一个mapping,上面例子中的urls;第二个fvars,例子中的globals(),globals()是python自带的一个函数,其返回值是全局名字空间,包括了函数、类、导入模块等等,是一个字典类型;第三个autoreload,是否允许自动重新载入。 mapping初始化 self.init_mapping(mapping) def init_mapping(self, mapping): self.mapping = list(utils.group(mapping, 2)) 最后mapping的形式会是[[‘1’,‘2’],[‘1’,‘2’]]这样,这边就可以理解urls列表的样式了。 _load和_unload变成钩子加入到processors 关于钩子和处理器详见官网。 self.add_processor(loadhook(self._load)) self.add_processor(unloadhook(self._unload)) loadhook函数的作用就是在执行其参数传入的函数前执行一些操作,unloadhook则是在其后执行一些操作。这两个都类似于python的decorator。而_load和_unload则是将application实例本身加入web.ctx.app_stack或从其中移除。 如果autoreload不为True则初始化就到此为止了。在初始化的时候,如果autoreload为None,则回去参数读取web.config内的debug的值,默认为False,所以如果autoreload参数没有传入,一般都是不会自动加载,后面操作不会再去进行了。 Reloader和reload_mapping变成钩子加入到processors 和第二步相似,reload_mapping就是用来从新载入主的app,并初始化mapping。而Reloader则是在检查磁盘上任何模块是否有变化,如果有则重新加载。 重新import 通过main获取主app所在的模块名称和所在文件名,然后通过文件名重新import。这步还是简单的,不过代码值得一看,可以学好如sys.modules、getattr()及__import__()的用法。 启动服务 def run(self, *middleware): return wsgi.runwsgi(self.wsgifunc(*middleware)) run函数调用wsgi模块的runwsgi函数,在hello world中就是启动一个http simple服务。具体内容等看到wsgi模块和httpserver模块再说了。

April 3, 2014