tags:

views:

47

answers:

2

I have a simple form in python + pylons that submits to a controller. However, each page load doesn't seem to be a fresh instantiation of the class. Rather, class variables specified on the previous page load are still accessible.

What's going on here? And what's the solution?

+1  A: 

Pylons uses a multi-threaded application server and variables are not cleared from request to request. This is a performance issue, as re-instantiating entire class trees would be expensive. Instead of storing the data returned by the user in a class, use a sessions system (Pylons comes with one or use something like Beaker) or back-end database like SQLAlchemy, SQLObject, or PyMongo.

Additionally, due to the multi-threaded nature of the framework, you should avoid shared objects (like globals) like the plague unless you are very careful to ensure you are using them in a thread-safe way (e.g. read-only). Certain Pylons-supplied objects (request/response) have been written to be thread-local, so don't worry about those.

GothAlice
Thanks. I'm just trying to do some simple form processing before storing the sane values into a db via SQLAlchemy (checking that an email is valid and doesn't already exist in the database). Should I clear the variables in the functions in the class?
ensnare
Use method-local variables, not variables in the global scope or which utilize 'self' to access. Method-local variables -will- be cleared between calls, as Python naturally rebuilds the local namespace on each call. This may mean you need to pass variables to other methods directly (rather than assigning to self, then calling another method with no arguments), but that isn't a bad thing; it makes code clearer and easier to understand.Remember PEP20: simple is better than complex, and readability counts.
GothAlice
+1  A: 

A common programmer oversight is that defining a list [] as a default argument or class initialiser is evaluated only once. If you have class variables such as lists, I recommend you initialise them in init. I'll give you an example.

>>> class Example(object):
...     a = []
...     def __init__(self):
...         self.b = []
... 

>>> foo = Example()
>>> bar = Example()

>>> foo.a
[]
>>> bar.a
[]
>>> foo.b
[]
>>> bar.b
[]

>>> foo.a.append(1)
>>> foo.b.append(2)
>>> foo.a
[1]
>>> foo.b
[2]
>>> bar.a
[1]
>>> bar.b
[]
Nick Sonneveld
This was very helpful. Thank you.
ensnare