首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python/GAE属性错误- webapp2

Python/GAE属性错误- webapp2
EN

Stack Overflow用户
提问于 2012-12-15 03:08:57
回答 3查看 925关注 0票数 3

我正在使用Nick Johnsons Webapp & Templates应用程序作为我想要做的事情的基础。当我尝试调用render_template时,我得到一个"AttributeError:'NoneType‘object has no attribute 'write'“。我知道这是因为当我将对象"Capture“实例化为X时,它没有response属性。我到处寻找解决方案,但我在任何地方都找不到。

注意:还有其他方法可以做到这一点,但我需要它的工作方式,因为我有它的设置!

回溯:

代码语言:javascript
复制
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

代码语言:javascript
复制
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)

我做错了什么?任何帮助/建议都非常感谢!

EN

回答 3

Stack Overflow用户

发布于 2012-12-15 04:00:54

如果您将calculateYear作为BaseHandler类的函数(或其他更适用的函数),它是否符合您的标准?正如您所猜到的,您的x没有被视为正确的response。当您调用webapp2.RequestHandler处理程序时,它将调用与请求类型相关联的方法(因此,在您的示例中,由于您正在发布一个表单,因此它将调用post(),如您所知)。当您实例化x并调用calculateYear时,您并没有指定特定的方法(def get(self)def post(self)等),因此不需要准备response (当我有机会时,我会深入研究一下以确认这确实是真的--我可能会弄错:)。

现在还不能对此进行测试,但是假设您需要从CaptureDetails处理程序以外的其他地方调用calculateYear,那么这种方法可以工作吗?在这里,您将在post方法的上下文中引用self,该方法将调用response处理:

代码语言:javascript
复制
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处理程序调用它,如下所示:

代码语言:javascript
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2012-12-15 04:02:23

通过在CaptureDetails.post方法中自己实例化Calculate,您创建它的方式与WSGIApplication不同,因此属性不可用。具体地说,您没有向它传递response,所以尝试引用它也就不足为奇了。

在本例中,我将把calculateYear的内容复制到您的post方法中-通过创建实例然后对其调用该方法,您实际上并没有保存任何东西。如果calculateYear变得更复杂,并且您不希望重复,那么我将引入一个新方法,您的两个处理程序方法都可以调用该方法。(虽然从这个示例中并不清楚Calculate类为什么存在-它没有'get‘方法,所以像您所做的那样将它映射到/age是行不通的。)

票数 1
EN

Stack Overflow用户

发布于 2012-12-15 03:36:14

尝试使用self.response.out.write而不是self.response.write

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13884815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档