为什么CherryPy对象属性在请求之间是持久的?

4 投票
2 回答
2070 浏览
提问于 2025-04-16 05:15

我在为我的CherryPy应用写调试方法。这里的代码大致是这样的:

import cherrypy

class Page:
    def index(self):
        try:
            self.body += 'okay'
        except AttributeError:
            self.body = 'okay'
        return self.body
    index.exposed = True

cherrypy.quickstart(Page(), config='root.conf')

我很惊讶地发现,从一个请求到另一个请求,self.body的输出在不断增加。当我从一个客户端访问页面,然后又从另一个同时打开的客户端访问,再刷新两个浏览器时,输出的内容变成了一串越来越多的“okay”。在我的调试方法中,我还记录了用户特定的信息(也就是会话数据),这些信息也出现在了两个用户的输出中。

我猜这是因为Python模块被加载到工作内存中,而不是每次请求都重新运行。

我的问题是:这是怎么回事?为什么self.debug在请求之间得以保留,而cherrypy.session和cherrypy.response却没有?

有没有办法设置一个对象属性,只在当前请求中使用?我知道我可以在每个请求中覆盖self.body,但这看起来有点随意。在CherryPy中有没有标准或内置的方法来做到这一点?

(第二个问题已移至 CherryPy缓存是怎么工作的?

2 个回答

5

你说得对,之所以从self.body得到相同的数据,是因为在运行CherryPy的Python进程中,这些数据在内存里是一样的。

self.debug是用来保持“状态”的,这个状态是服务器在运行时的一个属性。

如果你想为当前会话设置数据,可以用cherrypy.session['字段名'] = '字段值',要获取数据则用cherrypy.session.get('字段名')。

作为程序员,你不需要知道会话ID,cherrypy会帮你处理这个问题——会话ID是由cherrypy自动生成的,并且在浏览器和服务器之间通过cookie进行交换,这样在后续的请求和响应中就能保持会话。

如果你在配置中没有指定cherrypy.session的存储类型,它会默认存储在内存中(服务器和你都可以访问),不过你也可以选择把会话文件存储在磁盘上,这样可能会更方便调试,而不需要写很多代码来查找会话ID或键值对。

想了解更多信息,可以查看 http://www.cherrypy.org/wiki/CherryPySessions

5

synthesizerpatel的分析是正确的,但如果你真的想在每次请求中存储一些数据,最好把它作为一个属性存储在cherrypy.request上,而不是放在会话中。每次请求都会生成新的cherrypy.request.response对象,所以你不用担心它们的属性会在不同请求之间保留。这是标准的做法。只要确保你不要覆盖cherrypy内部的属性就可以了!比如,cherrypy.request.body已经被保留用来处理你发送的POST请求的JSON数据。

关于作用域具体是如何工作的,最好的参考资料是源代码

撰写回答