Python / Tornado类包装器缓存问题

时间:2015-10-03 03:59:11

标签: python arrays tornado python-internals

我正在实现Python的数组数据结构的包装器。我在我的应用程序中出于实际原因这样做,但是这个示例代码仅用于重现问题。通过Tornado抽象,每个请求似乎都没有“清除”该数组。

如果我不使用我的数组抽象,那就没问题了。这让我相信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用户,但如果它甚至无法处理简单的抽象,这种类型的东西会阻止我使用该语言。

附加

运行此:

  • pip install tornado
  • 安装Tornado软件包
  • 保存我在名为app.py
  • 的文件中提供的代码
  • 执行python app.py
  • 在您的浏览器中打开http://127.0.0.1/client
  • 的Web应用程序

1 个答案:

答案 0 :(得分:0)

问题是因为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)