0

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

我从这里的这个例子开始

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

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 设置/获取,最好的实现是什么?到目前为止,我对 ContextManager 的理解是,该with语句允许您通过上下文方法“程序化”执行一个类,不是吗?我的意思是,在我看来,用于描述流程的魔术方法__init__()>> __enter__()>>似乎是用来描述流程的__exit__()with如果我根据需要初始化变量,则在enter () 中进行查询,然后在 处删除类的实例,在__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变量不会打印在模板上,甚至在将其传递给模板之前尝试将 if 转换为字符串(虽然这不是一个大问题,我只想知道为什么)。页面上的结果是:

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

这种方法有问题吗?有什么注意事项或需要注意的事项吗?以这种方式在处理程序中使用它是正确的方法吗?

4

1 回答 1

0

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

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

希望这将帮助某人将一些面向对象应用到他们的 App Engine 项目中。

于 2014-01-10T13:18:15.603 回答