OK, but first you need to know some things about the python object system:
Classes are themselves objects, unlike in other languages (like Java, where they are just magical things brought to you by the JVM which don’t fit in Java in any other way). In fact, when you create a new object from a class, you are just calling it, like a function. You can create yourself objects that are callable, like in C++ with “operator ()”, and create in that way “Functor” objects (C++ programmers should have heard this, they are just that: Objects which are acting like a function, eg. you can call them). Functions are instances of the “Function” class (You can import it: “from types import FunctionsType” ).
>>> class A(object):
def __call__(self, a, b):
return a + b + 42
>>> a = A()
>>> a(3, 3)
48
Classes have so-called metaclasses, which are the classes of themselves. Since a class is somewhat of a “building plan” for a specific object, a metaclass is a building plan for the building plan. The standard metaclass every class is using is “type”. You can even create new metaclasses, either completly or you simply inherit from “type” and extend in the ways you need.
So, after that: A class variable of a class named “A” is a instance variable of the metaclass and has the specific property that it’s reachable from instances of the class “A”.
>>> class M(type):
def __init__(self, my_variable, *args, **kwargs):
self.my_variable = my_variable
type.__init__(self, *args, **kwargs)
>>> class A(object):
__metaclass__ = M
>>> A.my_variable
'A'
>>> A().my_variable
'A'
Don’t let this confuse you, it works just like other classes, with the exception that on creation of the class the class M is used to instantiate it - The class you have in the end is an instance of M. You can create standard classes even with type (or other metaclasses) yourself, by just instantiating it:
>>> def __init__(that_other_self, x):
that_other_self.x = x
>>> MyNewClass = type("Name", (object,), {"an_method": lambda self: self.x + 42, "__init__": __init__})
>>> my_new_class = MyNewClass(8)
>>> my_new_class
<__main__.Name object at 0xb7ea6f0c>
>>> my_new_class_instance = MyNewClass(8)
>>> my_new_class_instance
<__main__.Name object at 0xb7ea930c>
>>> my_new_class_instance.an_method()
50
The first parameter of a metaclass (constructor) is the name, the second the classes it should inherit from and the third a dictionary with all attributes (functions and variables) which an object of the class should own.
Since writing metaclasses everytime you need a class variable would be tiresome, python uses the class body for that:
>>> class A(object):
my_class_variable = 5
>>> A.my_class_variable
5
>>> A().my_class_variable
5
Note that therefore, every method you write is also a class variable - it is just reachable by the objects. When you change a class variable on the class, all objects notice:
>>> print a.my_class_variable, another_a.my_class_variable
5 5
>>> A.my_class_variable = 20
>>> print a.my_class_variable, another_a.my_class_variable
20 20
Now comes something very important: When you set a name in python on something, the most local namespace available is used. So when you change the variable on an instances, the instance namespace is used and you create a new instance variable, which shadows the old class variable:
>>> another_a.my_class_variable = 10
>>> print a.my_class_variable, another_a.my_class_variable
20 10
>>> print A.my_class_variable
20
So you create real instance variable in init, the constructor of the object:
>>> class A(object):
def __init__(self, some_name):
self.some_name = some_name
self.xyz = 42
>>> a = A(4)
>>> print a.some_name
4
>>> print a.xyz
42
>>> print A.some_name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute 'some_name'</module></stdin>
So, in short a class variable is something the class manages as opposed to something the object manages. When you change it on the class, all objects notice immediatly.
So when I construct something like you did in your code, this happens:
>>> class A(object):
handlers = []
def set_handler(self, handler):
self.handlers.append(handler)
>>> a, another_a = A(), A()
>>> a.set_handler("my_first_pseudo_handler")
>>> another_a.set_handler("another handler")
>>> print a.handlers
['my_first_pseudo_handler', 'another handler']
>>>
You see that in fact you have changed all handlers for all objects which exist. When you want handlers for every object, you have to create instance variables in init:
>>> class A(object):
... def __init__(self):
... self.handlers = []
... def set_handler(self, handler):
... self.handlers.append(handler)
...
>>> a, another_a = A(), A()
>>> a.set_handler("my_first_pseudo_handler")
>>> another_a.set_handler("another handler")
>>> print a.handlers
['my_first_pseudo_handler']
>>> print another_a.handlers
['another handler']
So it’s not right to use the class body for variables which you don’t need to be given in init.
One last important thing to notice is that this concept does not include methods of the metaclass, since functions you write in the class body are considered a variable and are just distributed to the instances of that class. To include this concept, python uses the class “classmethod”:
>>> class A(object):
def my_class_method(cls, bla):
print bla
print cls
my_class_method = classmethod(my_class_method)
>>> A.my_class_method(42)
42
<class '__main__.a'=""></class>
Note that you can also use classmethod as a decorator:
>>> class A(object):
@classmethod
def blub(cls):
pass
>>> A.blub
<bound method="" type.blub="" of="" <class="" '__main__.a'="">></bound>
(That is, by the way, really all decorators do - they expect to find an unary callable object and use it on the function (or class, in python greater than 2.6) you define next, rebinding the name. This was introduced since the concept is mighty (Functions as first order objects or you could also say the concept of “Higher order functions” ) and perfectly doable in python without decorators, but does hide the sense of the code when you don’t look closely what is written directly after the definition.)
For what do you need classmethods? There are many things you rather want the class to do than the object it creates (and it is really a great concept to work with), but the standard example are “alternate constructors”:
>>> class A(object):
def __init__(self, standard_format):
self.thing_in_standard_format = standard_format
@classmethod
def from_string(cls, another_format):
# So say we need in the normal constructor a number:
return cls(int(another_format))
>>> a = A.from_string("42")
>>> print a.thing_in_standard_format
42
>>> print type(a.thing_in_standard_format)
You could also write a classmethod named “from_file_object” which does just that. In other languages you would be forced to use normal functions which you group to the class, but that is really something the class should encapsulate, not it’s instances. Also note that this way you can inherit a class from another which uses classmethods and overwrite them: Any function which relies on the classmethod will not notice whether you gave it your subclass or the class from which you subclass inherited (this is called “polymorphism” ). Alone for this advantage it’s all worth it.
These concepts make python a really great language to work in. Many things in python are build upon a few basic concepts, and this hole class thing I just explained is one of them. All you have in python are objects from some classes, this is true everywhere, for every thing you can reach - things like “def some_function” are also just convenient abbreviations for the real thing, as I just showed with metaclasses. Python does much to hold up it’s minimalism, for example is type and instance of itself. This is done in C code and just works because of that.
Also, note that I inherited from “object” everywhere. The class system as I explained it was rewritten in python 2.1 and we have up to python 2.6 two sort of classes: The “Oldstyle” classes (which are the ones before 2.1) and the NewStyle Ones (which are those which inherit from object). In python 2.6 and greater you don’t need to inherit from object anymore and get NewStyle classes automatically. But before that, you should inherit from object. The OldStyle classes are deprecated and no longer supported (and are in many ways weaker than the NewStyle ones).
With these concepts in mind, you can do great things in python. The problem is that many tutorials don’t mention them. The official one I linked to does. Hope this helps you.