I've read What are Class methods in Python for? but the examples in that post are complex. I am looking for a clear, simple, bare-bones example of a particular use case for classmethods in Python.
Can you name a small, specific example use case where a Python classmethod would be the right tool for the job?
Well
__new__
is a pretty important classmethod. It's where instances usually come fromso
dict()
callsdict.__new__
of course, but there is another handy way to make dicts sometimes which is the classmethoddict.fromkeys()
eg.
I find that I most often use
@classmethod
to associate a piece of code with a class, to avoid creating a global function, for cases where I don't require an instance of the class to use the code.For example, I might have a data structure which only considers a key valid if it conforms to some pattern. I may want to use this from inside and outside of the class. However, I don't want to create yet another global function:
I'd much rather group this code with the class it's associated with:
I don't know, something like named constructor methods?
Usage:
The biggest reason for using a
@classmethod
is in an alternate constructor that is intended to be inherited. This can be very useful in polymorphism. An example:Notice that
Shape
is an abstract class that defines a classmethodfrom_square
, sinceShape
is not really defined, it does not really know how to derive itself from aSquare
so it simply returns a default instance of the class.Inherited classes are then allowed to define their own versions of this method:
The usage allows you to treat all of these uninstantiated classes polymorphically
This is all fine and dandy you might say, but why couldn't I just use as
@staticmethod
to accomplish this same polymorphic behavior:The answer is that you could, but you do not get the benefits of inheritance because
Circle
has to be called out explicitly in the method. Meaning if I call it from an inherited class without overriding, I would still getCircle
every time.Notice what is gained when I define another shape class that does not really have any custom from_square logic:
Here you can leave the
@classmethod
undefined and it will use the logic fromShape.from_square
while retaining whocls
is and return the appropriate shape.Helper methods for initialization: