在使用webpy的session时经常会发现按照文档是说明构造的session用法却总是出错,和预想差异很大。通过跟踪webpy源码发现原来默认情况下webpy在session这块儿做了很多手脚。举例如下:
(1)session不能在debug模式中使用
(2)session不能在webpy内置的wsgi server中使用
究其原因是因为webpy在debug或者内置wsgi server中使用的时候启用了模块级的reload,reloader 加载了主模块零次,一次是作为__main__被加载,一次是作为真正的文件被加载,这样就导致了程序中使用的session不是同一个。通过查看webpy源码中的application.py/modname()函数可以发现:
def main_module_name():
mod = sys.modules['__main__']
file = getattr(mod, '__file__', None) # make sure this works even from python interpreter
return file and os.path.splitext(os.path.basename(file))[0]
def modname(fvars):
"""find name of the module name from fvars."""
file, name = fvars.get('__file__'), fvars.get('__name__')
if file is None or name is None:
return None
if name == '__main__':
# Since the __main__ module can't be reloaded, the module has
# to be imported using its file name.
name = main_module_name()
return name
mapping_name = utils.dictfind(fvars, mapping)
module_name = modname(fvars)
为解决这一问题(毕竟使用webpy内置webserver调试程序还是很方便的),可以在启动webpy application之前做一点儿小手脚,具体代码如下:
here we will use the session to store global variables
# use this to bypass the webpy reloader
if web.config.get("_session") is None:
# set initial
perms = PermWrapper({})
from web import utils
user = utils.Storage({"user_login":
"Anonymous"})
session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={"perms": perms,
"user": user})
web.config._session = session
else:
session = web.config._session