Is it better to use class variables or pass parameters?

Duncan Booth duncan.booth at invalid.invalid
Thu Mar 2 09:45:32 CET 2006

Derek Basch wrote:

> This one has always bugged me. Is it better to just slap a "self" in
> front of any variable that will be used by more than one class method
> or should I pass around variable between the methods?

Try to distinguish the state of the object from the parameters to methods.

An object should always have a consistent state. Say you call a method, and 
that method calls a bunch of other methods. At almost any point during 
those method calls execution can leak out to other bits of code (e.g. you 
might think you are adding two values, but perhaps they have a user defined 
addition operator) and that other code might just call methods on the same 
object. This might not happen much in practice, but I think that if you 
imagine all method calls as potentially happening in parallel it avoids a 
lot of problems.

So, for example, if you had a method which returned a formatted 
representation of something, and which took a precision as a parameter, you 
shouldn't be saving the precision in the object: it isn't part of the 
state, and if you save it as such one day you might find it changes under 
your feet mid call.

A lot of objects benefit from being treated as immutable: i.e. initialise 
them on creation, but never modify the attributes after creation. This has 
the great benefit that you never need to worry about whether or not to copy 
an object: you always just keep using the same object until an attribute 
needs to change and then you just create a new one. Obviously this only 
works for lightweight objects, but that should be most of them.

Passing one or two parameters around a host of methods is fine: if you are 
passing more then it probably indicates you need to invent another object 
to encapsulate the state associated with the method call. It is also likely 
that it means you then want to move some of the code logic into the new 
object. In other words, instead of:

   obj.meth1(a, b, c, d) calls obj.meth2(a, b, c, d) calls obj.meth3, ...

(and perhaps meth2 only needs a, b and c so it can pass them on),
you want some helper object constructed with a, b, c & d and parts of the 
original methods then get factored into methods on the help objects.

More information about the Python-list mailing list