from google.appengine.ext.webapp import RequestHandler, WSGIApplication, util import os, sys dev_server = os.environ.get('SERVER_SOFTWARE').lower().startswith('dev') class lazy_loader(object): def __init__(self, fullname): self.modulename, sep, self.objname = fullname.rpartition('.') if dev_server: self() def __call__(self): try: return self.obj() except AttributeError: if not sys.modules.has_key(self.modulename): __import__(self.modulename, globals(), locals(), [], 0) self.obj = sys.modules.get(self.modulename).__dict__.get(self.objname) return self.obj() application = WSGIApplication([(route[0], lazy_loader(route[1])) for route in [ (r'/', 'handlers.MainPage'), (r'/search/', 'handlers.Search'), (r'/_ah/queue/sendmail', 'mail.SendMail'), (r'/_ah/queue/HeavyTask', 'tasks.HeavyTask'), ]], debug=os.environ.get('CURRENT_VERSION_ID').lower().startswith('dev')) def main(): util.run_wsgi_app(application) if __name__ == '__main__': main()
if dev_server: self.__call__()
only makes it easier to debug on the development server and you can do without it. The definition of the development server is outside the scope of the function to increase performance.lazy_loader
immediately passes the call. The construction with catching AttributeError
chosen because the self.obj
object should be present in most cases (if the name of the object is correct, then it will be absent only on the first call). If you instead check self.obj
on every call, the application will perform unnecessary operations; a bit, but still ... For the "lost" AttributeError
(if such suddenly appear in the handler's code) you can not worry - they will still pop up on the second call of the handler.self.obj
calls AttributeError
, during the processing of which the module is imported and the handler is received. Standard python expressions from package import module
can only import modules whose names are known at the design stage, so you can’t do without the powerful built-in function __import__ . We will use it in the simplest way - first import the module, and then get it from the sys.modules dictionary.sys.modules
, it is possible to check whether the necessary module has already been imported. In this example, the handlers
module will be imported only once during the lifetime of the instance.lazy_loader
to all list items (for example, (r'/', 'handlers.MainPage')
replaced by (r'/', lazy_loader('handlers.MainPage'))
.webapp
, depending on the version of the application specified in app.yaml
. Debug information will be issued only if the application version starts with “dev” (for example, develop
, dev-0-1-123
, dev-B1-37-2
, etc.)Source: https://habr.com/ru/post/128164/
All Articles