当请求(request)到来时,webpy对请求的处理流程在Application类的handle_with_processors方法中:
def handle_with_processors(self):
def process(processors):
try:
if processors:
p, processors = processors[0], processors[1:]
return p(lambda: process(processors))
else:
return self.handle()
except web.HTTPError:
raise
except (KeyboardInterrupt, SystemExit):
raise
except:
print >> web.debug, traceback.format_exc()
raise self.internalerror()
# processors must be applied in the resvere order. (??)
return process(self.processors)
可以看到,在处理请求时,会链式执行注册在processors列表中方法,如session的_processor方法,最后处理的是handle方法:
def handle(self):
fn, args = self._match(self.mapping, web.ctx.path)
return self._delegate(fn, self.fvars, args)
根据url来确定请求的处理方法并调用(路由)。
如果在创建application时设置autoreload=True时,修改程序自动重新加载,不需要重新启动应用,常用于开发时调试程序。
self.add_processor(loadhook(Reloader()))
将Reloader()加入调用链中。
另外,还将重新加载url路由表的逻辑加入调用链
self.add_processor(loadhook(reload_mapping))
当(url,handler)被修改时,application.mapping(请求路由表)能够跟着改变。
Reloader类的代码如下:
class Reloader:
"""Checks to see if any loaded modules have changed on disk and,
if so, reloads them.
"""
"""File suffix of compiled modules."""
if sys.platform.startswith('java'):
SUFFIX = '$py.class'
else:
SUFFIX = '.pyc'
def __init__(self):
self.mtimes = {}
def __call__(self):
#sys.modules.values()返回所有module的元组
for mod in sys.modules.values():
self.check(mod)
def check(self, mod):
# jython registers java packages as modules but they either
# don't have a __file__ attribute or its value is None
if not (mod and hasattr(mod, '__file__') and mod.__file__):
return
try:
#mod.__file__记录该module的文件(.pyc)路径
mtime = os.stat(mod.__file__).st_mtime
except (OSError, IOError):
return
#检查该module对应的py源文件的修改时间,取py/pyc修改时间的较大值
if mod.__file__.endswith(self.__class__.SUFFIX) and os.path.exists(mod.__file__[:-1]):
mtime = max(os.stat(mod.__file__[:-1]).st_mtime, mtime)
if mod not in self.mtimes:
self.mtimes[mod] = mtime
elif self.mtimes[mod] < mtime:
try:
reload(mod)
self.mtimes[mod] = mtime
except ImportError:
pass
在request的调用链中__call__方法被调用,检查import过的每个module是否在上一次check时修改过,如果修改过,就reload这个module,并记录这次该模块的修改时间。