[Tutor] class variables

Nick Lunt nick at javacat.f2s.com
Thu Jun 24 17:56:17 EDT 2004


Hi Alan,

thanks again for the explanation. Now I can see the relationship between
pythons class variables and javas static variables I understand what is
going on.

Thanks again,
Nick.

ps I apologise for replying to each response to my original email
seperately, I just thought it was the simplest way to do it. If that goes
against the etiquette of the list, please let me know.




-----Original Message-----
From: Alan Gauld [mailto:alan.gauld at blueyonder.co.uk]
Sent: 24 June 2004 22:05
To: Nick Lunt; Python Tutor
Subject: Re: [Tutor] class variables


> >From what you've both told me, it would seem that putting a local
variable
> in the __init__ method of a class is quite pointless,

No you often need to do that where the init does more than simple
initialisation.

Here is an example where init reads values from a file:

class C:
  def __init__(self,val)
     self.val = val
     temp = file("MySecretSettings.dat")
     self.setting1 = temp.readline().strip()
     self.setting2 = int(temp.readline().strip())
     temp.close
  def  someMethod(self):....

So temp is used as a local variable within init to hold the file
object,
but once read the file is never needed again so it is not stored as a
class or instance variable.

Local variables inside methods are just as useful as local variables
in any other function, but they have nothing to do with classes or
objects as such.

> But also, I can see no reason to use a class variable outside of a
class
> method with no self prefix.

It's for shared information. Instead of every instance of the class
having its own copy of the data they simply refer to the Class object
which stores it once. It also means that changes in that class value
can affect all instances of the class in one go:

class C:
   v = 2
   def __init__(self,msg):
       self.msg = msg
   def printit(self):
      for n in range(C.v): # uses class value
         print self.msg

a = C("Hello from A")
b = C("Hello from B")

for obj in [a,b]:
   obj.printit()  # both objects print 2 messages

C.v = 3  # Change behaviour of all instances here

for obj in [a,b]:
   obj.printit()  # both objects print 3 now


So we can control the behaviour of all our instances
at one stroke by changing the Class variable value.
This can be a very powerful technique, especially if
writing simulation software - eg network traffic
predictions - where you can change the network
parameters easily and do "What If" type scenarios
etc. (Imagine a mesh of network objects and you can
change the modelled protocol from IP4 to IP6 or X25
or ATM etc by changing one single value...)

Of course you could just use a regular global variable
but that's going against the principles of good OO design
and also is making the value visible to a wider namespace.
It's also less obvious that the value is related to the
class and finally means the user has to import the module
with the global defined. A Class variable gets inherited
so the user only needs to import the module where the
definition of the subclass exists and can access the class
variable from the superclass via the subclass:

class Super:
    v = 42
    pass

class Sub(Super):
    pass

x = Super()
y = Sub()

print Super.v, Sub.v
print x.v, y.v

And of course the definition of Sub could be in a different
module to Super...

> I admit Im quite confused by this still. Many python programs Ive
studied
> mix up class variable with and without the 'instance/self' prefix.

There shouldn't be many programs doing that, despite what I
just said class variables are relatively uncommon in most
programs. I doubt if I use them in more than about 10% of my
programs - at most!

> Im also confused about whether I should put my class variable inside
a
> method and use the self prefix, leave them outside of a method with
no
> prefix, or leave them outside of a method but give them a prefix.

Either outside a method with no prefix - a class variable,

or

Inside a method with a self prefix - an instance variable.

The former will be a shared value across all instances (and
even when no instances exist!) the latter will have a distinct
value for each instance.

You should never need to use a variable outside a method
with a self prefix. Note you can access the class variables either
through the class name (as I did in my example, coz I think
the intent is clearer) or using self. Python will look for it
locally and if not finding it will look in the class.

> With the simple programs I write at the moment, it wouldnt really
make much
> difference how I did it in most cases, but I would like to know when
I
> should or shouldn't be using self. And when I should be putting
class
> variables outside a class method (if ever).

Mostly put them inside init with self. Only if you want to share
the same value over all instances should you put it outside.

> I apologise for not grasping it very quickly. My previous
experiences with
> classes comes from java, and that was a while ago, and java classes
seem a
> lot stricter than python classes.

Java classes are frankly a bit weird, mainly because Java made
a lot of stupid decisions early on in an attempt to simplify things.
Then when they needed to do clever stuff they had to find weird ways
round the limitations they had built for themselves - inner classes
being a prime example. A lot of Java things are very bad OO design
but are needed because of the "simplifications" inherent in the
language!

The Java equivalent of class methods is static variables.

HTH,

Alan G
Author of the Learn to Program web tutor
http://www.freenetpages.co.uk/hp/alan.gauld




More information about the Tutor mailing list