Friday, February 5, 2010

The difference between staticmethod and classmethod in python

well, since i am a person that depend heavily on the vast opensource community as a hough resource of knowledge. I like to be able to contribute with the little knowledge that i gain.
So today i will explain the difference between staticmethod and classmethod in python, lets start..

You may have read a couple of python books/tutorials and i think that none of them mentions the difference between the staticemethod and classmethod decorator, even some tutorials says that there is no difference at all !!!

Why would i need to use static/class methods?

static/class methods are methods that binded to the class they created in not the object of that class, so you dont need to make an instance object of the class to call these methods, and it is used when your method doesnot depend on any object specific attributes.

Example of static method:

class FactoryClass(object):
@staticmethod
def createObject(objectType):
do some stuff


the code just define a class called FactoryClass and define a static method in this class called createOject, so how would it be to do the same using class method

Example of class method:

class FactoryClasss(object):
@classmethod
def createObject(cls, objectType):
do some stuff

so not so much of a difference ha, the only thing that is different is that the class method is passed the class object by default as its first paramter, so what i can do wiht the class object paramters ?
lets say that you not only want to create object of a certain type but also you want to make sure that at any point of time there is only one instance object of each type.
Ok easy, the first thing you would think of is to create an attribute(map) that hold each type as key and the value is the object and in the createObject method you will check if the type already exits in the map, then you will not create any new instance but will return the already created one, lets do that

Using class method:

class ClassFactory(object):
objectMap = dict()
classMap = {'type1': Class1, 'type2': Class2}
@classmethod
def createObject(cls, objectType):
if objectType in cls.objectMap:
return cls.objectMap.get(objectType)
else:
object = cls.classMap.get(objectType)
cls.objectType[objectType] = object
return object

pretty neat ha, but it does not mean you cannot do that using a static method, the thing is that it will not be as clean as the class method one, lets have a look

Using static method:

class ClassFactory(object):
objectMap = dict()
classMap = {'type1': Class1, 'type2': Class2}
@staticmethod
def createObject(objectType):
if objectType in ClassFactory.objectMap:
return ClassFactory.objectMap.get(objectType)
else:
object = ClassFactory.classMap.get(objectType)
ClassFactory.objectType[objectType] = object
return object

hope it helps...