Entry
What is a "classmethod" for?
How is "classmethod" different from "staticmethod"?
Jan 14th, 2008 09:33
Michael Chermside, Dennis Peterson, Ian Bicking
Here is a class with a staticmethod and a classmethod:
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class C:
... @classmethod
... def foo(cls):
... print 'class is %s' % cls
...
Then we will declare a subclass, and an instance of each class:
>>> class D(C):
... pass
...
>>> c = C()
>>> d = D()
Now let us demonstrate that staticmethods and classmethods can be called
from the class object or from an instance:
>>> [C.static(), C.classMthd(), c.static(), c.classMthd()]
static method of class C
classmethod, cls = __main__.C
static method of class C
classmethod, cls = __main__.C
[None, None, None, None]
>>> [D.static(), D.classMthd(), d.static(), d.classMthd()]
static method of class C
classmethod, cls = __main__.D
static method of class C
classmethod, cls = __main__.D
[None, None, None, None]
So... what's the point? Why would a thing like this be useful, and what
is the difference? Staticmethod is simpler, so we'll consider that
first. Staticmethod is modeled on the "static" modifier from Java and
some other languages. The method is really just a function that has
nothing whatsoever to do with the class or the instance it is being
called from. In Python, it might as well be a top-level function (they
don't have those in Java), and usually that is considered the more
"pythonic" approach, so that staticmethod is used only rarely in Python.
(For instance: to mimic the API of a library from another language, or
to support a model where only a class is imported not an entire module.)
The classmethod modifier is a somewhat more powerful construct. It is
passed a parameter telling the class that it was actually invoked on (or
class of the instance it was actually invoked on). The basic reason for
using classmethod is if your class has class variables which need to be
used. Just like object methods need to have "self" passed in so they can
access the instance variables available there, classmethods have "cls"
passed in so they can access the class variables.
So, for instance, suppose that your class kept a per-class cache of
instances:
>>> class Cached:
... cache = {} # Contains values of (expire_time, cache_value)
... @classmethod
... def cleanCache(cls):
... for key, (expire_time, value) in cls.cache.items():
... if expire_time < time.time():
... del cls.cache[key]
...
Here you can see how the "cls" variable is used.