Context Manager和Object Oriented可以有效地用于GAE请求处理程序类

时间:2014-01-08 03:06:18

标签: python google-app-engine oop with-statement contextmanager

我可以在请求处理程序中使用上下文管理器来管理从URL到模板的变量流吗?

我从这个例子开始here

我正在考虑使用它在处理程序的顶部创建一个类实例,运行我需要计算的所有代码,关闭上下文并将类计算的所有变量传递给参数字典最后将它们传递给模板。 像:

URL>>> http://domain.xx/param1/param2/

class Handler(webapp2.RequestHandler):
 def get(self, param1, param2)
  URLparams = [param1,param2]
  TEMPparams = {}
  with Foo(URLparams) as foo:
     TEMPparams['obj'] = foo.obj
     TEMPparams['obj1'] = foo.obj1
     ... 
  self.response.out.write(template, TEMPparams)

class Foo(object):
  def __init__(self, URLparams):
      ...
      ...
  def __enter__ ... :
      ... make a db query ...
  def __exit__ ... :
      ... 

考虑到我必须在类中执行数据存储区查询和一些memcache set / get,最佳实现是什么? 对于我迄今为止对ContextManager的理解,with语句允许您通过上下文方法使“程序化”执行类,不是吗? 我的意思是,魔术方法__init__()>> __enter__()>>与__exit__()一起使用的with似乎在描述流程。如果我根据需要初始化变量,我在输入()中进行查询,然后在__exit__()删除类'实例,在我看来模拟OO中的过程范例

我测试过这样的事情:

class Test(webapp2.RequestHandler):
  def get(self):
    r = []
    p = {}      
    foo = Foo(r)
    with foo:
        p['obj'] = [foo, foo.bar, r]

    self.response.out.write(p)

class Foo(object):

  def __init__(self, r):
    self.bar = None
    self.r = r

  def __enter__(self):
    if self.bar != 'open':
      r = self.r
      r.append('opening the bar')
      self.bar = 'open'
    return self # this is bound to the `as` part

  def close(self):
    if self.bar != 'closed':
      r = self.r
      r.append('closing the bar')
      self.bar = 'close'

  def __exit__(self, *err):
    self.close()
    return self.r  

模板上没有打印foo变量,甚至在将其传递给模板之前尝试将其转换为字符串(这不是一个大问题,但我只想知道原因)。 页面上的结果是:

{'obj': [, 'open', ['opening the bar', 'closing the bar']]}

这种方法有什么问题吗?有什么需要注意的警告或事情吗?以这种方式将它用于处理程序是否是正确的方法?

1 个答案:

答案 0 :(得分:0)

我现在能找到的最佳解决方案是构建一个自定义类来为处理程序中所需的任务创建一个通用对象,然后在每个请求处理程序中的__init__()中创建一个实例,如: / p>

class GenericalObject(object):
    def initialize(self, URIparams):
       # init all the self.attribute needed by my handlers

    def getDataFromDB():
       # return the DB data into a dictionary


class FirstHandler(webapp2.RequestHandler):
    def __init__(self, request, response):
       self.initialize(request, response)
       self.instance = GenericalObject()

    def get(self, URIparams1, URIparams2)
       URIparams = [URIparams1, URIparams2]
       instance = self.instance
       instance.initialize(URIparams)
       params = instance.__dict__

       data = getDataFromDB()
       params['data'] = data
       del instance

       return self.render_template('template.html', params)

class SecondHandler(webapp2.RequestHandler):
    # same initialization but different implementation of the get() and post()

感谢@TimHoffman

希望这有助于某人将某些OO应用到他们的App Engine项目中。