Python/GAE属性错误-webapp2

Python/GAE属性错误-webapp2,python,google-app-engine,jinja2,webapp2,Python,Google App Engine,Jinja2,Webapp2,我使用应用程序作为我尝试做的事情的基础。当我尝试调用render_模板时,我得到一个“AttributeError:'NoneType'对象没有属性'write'”。我知道这是因为当我将对象“Capture”实例化为X时,它没有response属性。我到处寻找解决办法,但到处都找不到 注意:还有其他方法可以做到这一点,但我需要它与我的设置方式密切相关 回溯: Traceback (most recent call last): File "/Applications/GoogleAppEng

我使用应用程序作为我尝试做的事情的基础。当我尝试调用render_模板时,我得到一个“AttributeError:'NoneType'对象没有属性'write'”。我知道这是因为当我将对象“Capture”实例化为X时,它没有response属性。我到处寻找解决办法,但到处都找不到

注意:还有其他方法可以做到这一点,但我需要它与我的设置方式密切相关

回溯:

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/Users/userx/Documents/_FRESHCUTZ MEDIA/Google/GAE - Test web form 1 /testwebform1/main.py", line 41, in post
    x.calculateYear(name, age)
  File "/Users/userx/Documents/_FRESHCUTZ MEDIA/Google/GAE - Test web form 1 /testwebform1/main.py", line 49, in calculateYear
    self.response.write(self.render_template('index.html', **template_args))
AttributeError: 'NoneType' object has no attribute 'write'
MAIN.PY

import os
import webapp2
from webapp2_extras import jinja2

class BaseHandler(webapp2.RequestHandler):
  @webapp2.cached_property
  def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

  def render_template(self, filename, **template_args):
        self.response.write(self.jinja2.render_template(filename, **template_args))

class MainPage(BaseHandler):
  def get(self):
    template_args = {}
    self.render_template('index.html', **template_args)

class CaptureDetails(BaseHandler):
  def post(self):
    name = self.request.get("name").strip()
    age = self.request.get("age").strip()

    x = Calculate()
    x.calculateYear(name, age)

class Calculate(BaseHandler):
    def calculateYear(self, name, age):
       template_args = {"age": age} 
       self.render_template('name.html', **template_args) 

app = webapp2.WSGIApplication([
      ('/', MainPage),
      ('/capture', CaptureDetails),
      ('/age', Calculate)
    ], debug=True)

我做错了什么?非常感谢您的帮助/建议

尝试使用
self.response.out.write
而不是
self.response.write
如果将
calculateYear
作为
BaseHandler
类的函数(或其他更适用的函数),它是否符合您的标准?正如您所猜测的,您的
x
没有被视为正确的
响应。当您调用
webapp2.RequestHandler
处理程序时,它将调用与请求类型相关联的方法(因此,在您的情况下,由于您正在发布表单,它将调用
post()
)。当您实例化
x
并调用
calculateYear
时,您没有指定特定的方法(
def get(self)
def post(self)
,等等),因此没有准备
响应(当我有机会时,我会挖掘一点来确认这是实际情况-我可能弄错了:)

现在无法测试这一点,但假设您需要从不仅仅是
CaptureDetails
处理程序调用
calculateYear
,这是否可行?这里,您将在
post
方法的上下文中引用
self
,该方法将调用
响应
处理:

class BaseHandler(webapp2.RequestHandler):
  @webapp2.cached_property
  def jinja2(self):
      return jinja2.get_jinja2(app=self.app)

  def render_template(self, filename, **template_args):
      self.response.write(self.jinja2.render_template(filename, **template_args))

  def calculateYear(self, name, age):
      template_args = {"age": age} 
      self.render_template('name.html', **template_args)
然后可以从
CaptureDetails
处理程序调用它,如:

class CaptureDetails(BaseHandler):
  def post(self):
    name = self.request.get("name").strip()
    age = self.request.get("age").strip()

    # Call the function and write the response
    self.calculateYear(name, age)

通过在
CaptureDetails.post
方法中实例化
Calculate
您自己,您创建它的方式与
WSGIApplication
不同,因此属性不可用。具体地说,您没有向它传递
响应
,因此毫不奇怪尝试引用它是无效的

在这种情况下,我会将
calculateYear
的内容复制到您的post方法中-您不需要创建实例,然后调用该实例上的方法来保存任何内容。
如果
calculateYear
变得更复杂,并且您不想重复,那么我将介绍一个新方法,它可以被您的两个hander方法调用。(从这个例子中还不清楚为什么存在
Calculate
类-它没有“get”方法,所以将它映射到
/age
,就像你所做的那样是行不通的。)

对于webapp2,“out”只是一个返回“self”以与webapp兼容的方法