Python/Tornado Class 包装缓存问题

Python/Tornado Class wrapper caching issue

我正在围绕 Python 的数组数据结构实现一个包装器。我在我的应用程序中出于实际原因这样做,但提供此示例代码只是为了重现该问题。对于通过 Tornado 抽象的每个请求,该数组似乎并不是 'cleared'。

如果我不使用我的数组抽象,就没有问题。这让我相信 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()

启动 python 进程后刷新页面后得到的输出顺序如下:

序列 1

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

序列 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}]

序列 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}]

此响应输出不是预期输出。预期输出的长度应为 JSON 输出数组的 6。如果我不包装 Python 的数据结构,这个问题就不会发生。

为什么会这样?我是一个热心的 Python 新用户,但是如果这种语言甚至不能处理简单的抽象,这种类型的事情会阻止我使用它。

额外

给运行这个:

问题是因为 Array._data 实际上是 Array 的静态成员,这意味着它的值在 Array.

的所有实例中都是相同的
class Array():
    _data = []
    def push(self, value):
        self._data.append(value)

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

要解决此问题,请将 _data 设为实例成员。

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

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

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