Web.py 之 Processor

Web.py 之 Processor

  • Processor

    • web.py 的processor 分为两种,api中有相关的convenient loadhookunloadhook
      对应了处理http响应之前和之后

    • code

      loadhook(h)

      def loadhook(h):
      """
      Converts a load hook into an application processor.
      
          >>> app = auto_application()
          >>> def f(): "something done before handling request"
          ...
          >>> app.add_processor(loadhook(f))
      """
      def processor(handler):
          h()
          return handler()
      
      return processor
      

      unloadhook(h)

      def unloadhook(h):
          """
          Converts an unload hook into an application processor.
      
              >>> app = auto_application()
              >>> def f(): "something done after handling request"
              ...
              >>> app.add_processor(unloadhook(f))    
          """
          def processor(handler):
              try:
                  result = handler()
                  is_generator = result and hasattr(result, 'next')
              except:
                  # run the hook even when handler raises some exception
                  h()
                  raise
      
              if is_generator:
                  return wrap(result)
              else:
                  h()
                  return result
      
          def wrap(result):
              def next():
                  try:
                      return result.next()
                  except:
                      # call the hook at the and of iterator
                      h()
                      raise
      
              result = iter(result)
              while True:
                  yield next()
      
          return processor
      
    • 相对loadhook,unloadhook要复杂一点,主要是体现在返回值是可迭代对象的时候。wrap函数主要是处理了迭代协议next。当迭代结束调用h进行处理。需要特别注意的是h在返回值是iter对象时的处理。wrap的作用只是在迭代结束之后给h调用的机会,而没有将iter对象迭代完成。因为这是考虑到大文件的处理

    • 使用起来也很简单

      app = auto_application()
      def hook_load(): "something done before handling request"
      def hook_unload(): "something done after handling request"
      app.add_processor(web.loadhook(hook_load)) 
      app.add_processor(web.unloadhook(hook_unload)) 
      
    • 实际的例子

      web.py的官方文档中对sub-application不能使用主应用中的session的解决方案

      def session_hook():
          web.ctx.session = session
      

      这样就可以在sub-application里面通过web.ctx.session调用到主应用的session了。

    • 也可以仿照上面的代码自己写一些处理,来处理http响应事件,比如

      def words_hook(words):
      
          def delegate(handler):
              return words + ':' + handler()
          return delegate
      
    • 上面的处理看似合理,其实和设计初衷不符,本意的loadhook和unloadhook除了简化processor函数的操作,还进一步指明了processor的用法,不会对handler的返回值做任何改动。因为根据hook_unload的实现,当返回iter对象的时候,处理会变的复杂,iter对象完成的往往是大文件操作。具体的应用可以具体分析,最后的分析只是针对一般情况。

你可能感兴趣的:(Web.py 之 Processor)