在使用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