I'm implementing a wrapper around Python's array data structure. 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.
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.
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:
Sequence 1
[{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}]
Sequence 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
[{"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. This problem does NOT happen if I don't wrap Python's data structure.
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.
Extra
To run this:
pip install tornado
,app.py
python app.py
http://127.0.0.1/client
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
.
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.
class Array():
def __init__(self):
self._data = []
def push(self, value):
self._data.append(value)
def json(self):
return json.dumps(self._data)