我正在实现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
,app.py
python app.py
http://127.0.0.1/client
答案 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)