self.response.out.write() - 如何正确使用它?

0 投票
1 回答
5739 浏览
提问于 2025-04-16 06:46

我有一个类,它没有继承 webapp.RequestHandler,所以我不能使用 self.response.out.write(),结果我得到了:

AttributeError: Fetcher 实例没有 'response' 属性

如果我让这个类继承 webapp.RequestHandler(我以为这样可以解决问题),结果却是:

AttributeError: 'Fetcher' 对象没有 'response' 属性

我该怎么正确使用这个方法呢?有时候 print 也不管用,我只看到一个空白的屏幕。

编辑:

app.yaml:

application: fbapp-lotsofquotes
version: 1
runtime: python
api_version: 1

handlers:
- url: .*
  script: main.py

源代码(有问题的那一行用 #<- HERE 标记出来):

import random
import os

from google.appengine.api import users, memcache
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import util, template
from google.appengine.ext.webapp.util import run_wsgi_app

import facebook


class Quote(db.Model):
    author = db.StringProperty()
    string = db.StringProperty()
    categories = db.StringListProperty()
    #rating = db.RatingProperty()


class Fetcher(webapp.RequestHandler):
    '''
    Memcache keys: all_quotes
    '''

    def is_cached(self, key):
        self.fetched = memcache.get(key)
        if self.fetched:
            print 'ok'#return True
        else:
            print 'not ok'#return False


    #TODO: Use filters!
    def fetch_quotes(self):
        quotes = memcache.get('all_quotes')
        if not quotes:
            #Fetch and cache it, since it's not in the memcache.
            quotes = Quote.all()
            memcache.set('all_quotes',quotes,3600)
        return quotes

    def fetch_quote_by_id(self, id):
        self.response.out.write(id) #<---------- HERE


class MainHandler(webapp.RequestHandler):

    def get(self):
        quotes = Fetcher().fetch_quotes()
        template_data = {'quotes':quotes}
        template_path = 'many.html'
        self.response.out.write(template.render(template_path, template_data))


class ViewQuoteHandler(webapp.RequestHandler):

    def get(self, obj):
        self.response.out.write('viewing quote<br/>\n')
        if obj == 'all':
            quotes = Fetcher().fetch_quotes()
            self.render('view_many.html',quotes=quotes)
        else:
            quotes = Fetcher().fetch_quote_by_id(obj)
            '''for quote in quotes:
                print quote.author
                print quote.'''


    def render(self, type, **kwargs):
        if type == 'single':
            template_values = {'quote':kwargs['quote']}
            template_path = 'single_quote.html'
        elif type == 'many':
            print 'many'

        self.response.out.write(template.render(template_path, template_values))


'''
CREATORS
'''
class NewQuoteHandler(webapp.RequestHandler):

    def get(self, action):
        if action == 'compose':
            self.composer()
        elif action == 'do':
            print 'hi'

    def composer(self):
        template_path = 'quote_composer.html'
        template_values = ''
        self.response.out.write(template.render(template_path,template_values))

    def post(self, action):
        author = self.request.get('quote_author')
        string = self.request.get('quote_string')
        print author, string

        if not author or not string:
            print 'REDIRECT'

        quote = Quote()
        quote.author = author
        quote.string = string
        quote.categories = []
        quote.put()


def main():
    application = webapp.WSGIApplication([('/', MainHandler),
                                          (r'/view/quote/(.*)',ViewQuoteHandler),
                                          (r'/new/quote/(.*)',NewQuoteHandler) ],
                                         debug=True)
    util.run_wsgi_app(application)


if __name__ == '__main__':
    main()

1 个回答

2

你在初始化一个 WSGIApplication 的时候,并没有把它指向 Fetcher。实际上,你是在其他处理程序里手动创建了一个实例。所以,App Engine 不会自动初始化你的 requestresponse 属性。你可以在你路由到的处理程序里手动初始化这些属性,比如 MainHandlerViewQuoteHandler。比如:

fetcher = Fetcher()
fetcher.initialize(self.request, self.response)
quotes = fetcher.fetch_quotes()

需要注意的是,fetcher 并不一定要是一个 RequestHandler。它可以是一个单独的类或者函数。一旦你有了请求和响应对象,你可以根据需要自由传递它们。

撰写回答