简体   繁体   English

Python/Tornado 类包装器缓存问题

[英]Python/Tornado Class wrapper caching issue

I'm implementing a wrapper around Python's array data structure.我正在围绕 Python 的数组数据结构实现一个包装器。 I'm doing this for practical reasons in my application, but this example code is just provided to reproduce the problem.我在我的应用程序中出于实际原因这样做,但提供此示例代码只是为了重现问题。 The array doesn't seem to be 'cleared' for each request through the Tornado abstraction.似乎没有通过 Tornado 抽象为每个请求“清除”数组。

If I don't use my array abstraction, there is no problem.如果我不使用我的数组抽象,就没有问题。 This leads me to believe there is a bug somewhere in the CPython implementation.这让我相信 CPython 实现中的某个地方存在错误。

from tornado import websocket, web, ioloop
import json

class Array():
    _data = []
    def push(self, value):
        self._data.append(value)

    def json(self):
        return json.dumps(self._data)


class ClientHandler(web.RequestHandler):
    def prepare(self):
        self.set_header("content-type", "application/json")

    def get(self):
        array = Array()

        for i in range(0, 6):
            array.push({'id': i})

        self.write(array.json())
        self.finish()

app = web.Application([
    (r'/client', ClientHandler),
], debug=True)

if __name__ == '__main__':
    kwargs = {"address": "127.0.0.1"}
    app.listen(port=8888, **kwargs)
    ioloop.IOLoop.instance().start()

The output I get after refreshing the page once I've started the python process is as follows in sequence:启动python进程后刷新页面后得到的输出顺序如下:

Sequence 1序列 1

[{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}]

Sequence 2序列 2

[{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}, {"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}]

Sequence 3序列3

[{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}, {"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}, {"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}]

This response out is not the expected output.此响应输出不是预期的输出。 The expected output should have a length of 6 of the JSON output array.预期输出的长度应为 JSON 输出数组的6 This problem does NOT happen if I don't wrap Python's data structure.如果我不包装 Python 的数据结构,这个问题就不会发生。

Why does this happen?为什么会发生这种情况? I'm a new enthusiastic Python user, but this type of thing discourages me from using the language if it can't even handle a simple abstraction.我是一个新的热情的 Python 用户,但是如果它甚至不能处理简单的抽象,这种类型的东西就会阻止我使用该语言。

Extra额外的

To run this:要运行这个:

  • install the Tornado package at pip install tornado ,pip install tornado安装 Tornado 包,
  • save the code I provided in a file called app.py将我提供的代码保存在名为app.py的文件中
  • execute python app.py执行python app.py
  • open the web application in your broswer for http://127.0.0.1/client在您的浏览器中为http://127.0.0.1/client打开 Web 应用程序

The issue is because Array._data is actually a static member of Array meaning it's value will be the same over all instances of Array .问题是因为Array._data实际上是Array的静态成员,这意味着它的值在Array所有实例中都是相同的。

class Array():
    _data = []
    def push(self, value):
        self._data.append(value)

    def json(self):
        return json.dumps(self._data)

To solve the problem, make _data an instance member.为了解决这个问题,让_data成为一个实例成员。

class Array():
    def __init__(self):
        self._data = []

    def push(self, value):
        self._data.append(value)

    def json(self):
        return json.dumps(self._data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM