【问题标题】:AppEngine Python - how to deal with cached object valuesAppEngine Python - 如何处理缓存的对象值
【发布时间】:2012-09-02 04:43:32
【问题描述】:

新手问题。

所以我有这个处理程序用于附加一些 CSS/JS 文件的页面。问题是后续请求将导致一次又一次地附加值。

例子:

def action_index(self):
    self.template = 'index.html'

    extra_styles = ['/media/css/jquery.lightbox-0.5.css']
    extra_scripts = ['/media/js/jquery.lightbox-0.5.min.js', '/media/js/project.js']

    for style in extra_styles:
        self.styles.append(style)

    for script in extra_scripts:
        self.scripts.append(script)

您通常如何在 Google AppEngine 等平台中处理此问题,因为我来自 PHP 背景,其中对象仅存在于当前请求中。

谢谢

根据要求,这是基类:

基本控制器

from google.appengine.ext.webapp import template 

import os
import config
import datetime

class BaseController(object):

    request = None
    response = None
    action = 'index'
    method = 'get'
    params = []
    template_values = {}
    template_dir = None
    template = None

    default_styles = ['/media/bootstrap/css/bootstrap.min.css', '/media/css/style.css']
    default_scripts = ['/media/js/jquery-1.6.4.min.js']

    styles = []
    scripts = []

    def __init__(self, request, response, *args, **kwargs):
        self.request = request
        self.response = response

        self.action = 'index'
        if 'action' in kwargs and kwargs['action']:
            self.action = kwargs['action']

        self.method = 'get'
        if 'method' in kwargs and kwargs['method']:
            self.method = kwargs['method']

        self.params = []
        if 'params' in kwargs and kwargs['params']:
            if isinstance(kwargs['params'], list):
                self.params = kwargs['params']

        # Initialize template related variables
        self.template_values = {}
        self.styles = list(self.default_styles)
        self.scripts = list(self.default_scripts)

    def pre_dispatch(self):
        pass

    def post_dispatch(self):
        if self.template is not None and self.template_dir is not None:
            # Populate current year
            dt = datetime.date.today()
            self.template_values['current_year'] = dt.year

            # Populate styles and scripts
            self.template_values['styles'] = self.styles
            self.template_values['scripts'] = self.scripts

            path = os.path.join(config.template_dir, self.template_dir, self.template)
            self.response.out.write(template.render(path, self.template_values))

    def run_action(self):
        action_name = 'action_' + self.action
        if hasattr(self, action_name):
            action = getattr(self, action_name)
            action()
        else:
            raise Http404Exception('Controller action not found')

    def dispatch(self):
        self.pre_dispatch()
        self.run_action()
        self.post_dispatch()

class HttpException(Exception):
    """Http Exception"""
    pass

class Http404Exception(HttpException):
    """Http 404 exception"""
    pass

class Http500Exception(HttpException):
    """Http 500 exception"""
    pass

还有子类

import datetime

from dclab.lysender.controller import BaseController

class ProjectsController(BaseController):

    template_dir = 'projects'

    def action_index(self):
        self.template = 'index.html'
        self.styles.extend(['/media/css/jquery.lightbox-0.5.css'])
        self.scripts.extend([
            '/media/js/jquery.lightbox-0.5.min.js',
            '/media/js/project.js'
        ])

我的错是我通过引用将一个列表分配给另一个列表,而不是克隆该列表。我不太清楚这种行为,这就是为什么它让我整晚都在挠头。

【问题讨论】:

  • 看起来参考分配让我很着急。我喊写 self.scripts = list(self.default_scripts) 代替,这适用于所有 python 对象吗?
  • 显示实际班级?看起来你想在构造函数中做这些事情,而不是这个 action_index() 方法是什么。这与您的实例如何被缓存有关,但没有足够的信息。
  • 嗨 gragonx,我已经通过克隆列表解决了这个问题,我不知道这个引用的东西,所以这就是问题所在。上面的代码已经可以工作了。刚刚更改了列表。

标签: google-app-engine python-2.7


【解决方案1】:

您在类定义下直接声明了很多变量。这样做不会像您期望的那样定义实例成员,而是定义类变量 - 相当于 Java 等语言中的“静态”。

不要将事物声明为类变量,而是在构造函数中初始化您的值 - 您的类的 __init__ 方法。

我还强烈建议使用现有的网络框架,如 webapp2,而不是自己发明。

【讨论】:

  • 是的,这正是我正在做的,将我的小应用程序/网站迁移到 webapp2 并丢弃我自己的代码。使用 init 比重写 dispatch() 更好吗?无论如何,这真的很有帮助。我仍然会研究:实例成员与类变量。
  • @Lysender 您的代码都没有使用 webapp - 您似乎正在发明自己的请求处理程序(BaseController)。使用__init__ 还是__dispatch__ 取决于您要执行的操作。
  • 我没有展示我的完整代码,它确实在使用 webapp(不是 webapp2)。我创建了自己的请求处理程序,包裹在 webapp 上,用于某种自动路由、自动模块导入等(与流行的 PHP 框架相同)。然而,当我看到 webapp2 时,我意识到 webapp2 确实是我需要的。
  • 这是我现在使用 webapp2 web.py的新基本处理程序
猜你喜欢
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 2012-10-14
  • 2023-03-03
  • 2017-03-17
  • 2015-04-06
  • 2015-05-31
  • 1970-01-01
相关资源
最近更新 更多