Python classmethod() Function
The classmethod()
function returns a class method for the given function.
Syntax
classmethod(function)
The classmethod()
function is considered un-Pythonic so in newer Python versions, you can use the @classmethod
decorator for classmethod definition.
@classmethod
def func(cls, args...)
classmethod() Parameters
Python classmethod()
function parameters:
Parameter | Condition | Description |
---|---|---|
function | Required | Function that needs to be converted into a class method |
classmethod() Return Value
Python classmethod()
function returns a class method for the given function.
What is a class method?
A class method is associated with the class itself, not with instances of the class, and can be invoked without creating an instance of the class, like a static method.
The difference between a static method and a class method is:
- Static method knows nothing about the class and just deals with the parameters
- Class method works with the class since its parameter is always the class itself.
The class method can be called both by the class and its object.
Class.classmethod()
or even
Class().classmethod()
But no matter what, the class method is always attached to a class with the first argument as the class itself cls
.
def classMethod(cls, args...)
Example: Create class method using classmethod()
class Person:
age = 25
height = 180
def printAge(cls):
print('The age is:', cls.age)
def printHeight(cls):
print('The height is:', cls.height)
# create printAge class method
Person.printAge = classmethod(Person.printAge)
# create printHeight class method
Person.printHeight = classmethod(Person.printHeight)
Person.printAge()
Person.printHeight()
output
The age is: 25
The height is: 180
Notice that
printAge()
andprintHeight()
take a single parametercls
and notself
(as in usual classes).- The method
Person.printAge
is passed as an argument to the functionclassmethod
. This converts the method to a class method so that it accepts the first parameter as a class (i.e.Person
). - The same is done for the
Person.printHeight
method. - Finally, you can call
printAge
andprintHeight
without creating aPerson
object, and so you can print the class variablesage
andheight
.
When do you use the class method?
Class methods are used in scenarios where a method is intended to be bound to the class and not the instance of that class. Here are the specific cases where you might use class methods:
1. Factory methods
Factory methods are class methods that serve as alternative constructors.
They are particularly useful when you need to create objects in a way that involves more logic than simply calling the class's constructor.
For example, if you have a class that represents different types of vehicles and you want to ensure that the correct vehicle type is created based on some input, a factory method could be used to encapsulate this logic
class Vehicle:
def __init__(self, vehicle_type):
self.vehicle_type = vehicle_type
def drive(self):
print(f"Driving a {self.vehicle_type}")
@classmethod
def factory(cls, vehicle_type):
if vehicle_type == "car":
return cls("Car")
elif vehicle_type == "bike":
return cls("Bike")
else:
raise ValueError("Invalid vehicle type")
# Usage
car = Vehicle.factory("car")
bike = Vehicle.factory("bike")
car.drive() # Output: Driving a Car
bike.drive() # Output: Driving a Bike
2. Correct instance creation in inheritance
Using class methods for factory implementations in inheritance ensures proper instantiation of subclasses.
A static method could achieve similar functionality but would only produce instances of the base class, limiting flexibility.
However, with class methods, you can generate the appropriate instances of the subclass that was invoked, thus providing the desired polymorphic behavior.
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@staticmethod
def fromFathersAge(name, fatherAge, fatherPersonAgeDiff):
return Person(name, date.today().year - fatherAge + fatherPersonAgeDiff)
@classmethod
def fromBirthYear(cls, name, birthYear):
return cls(name, date.today().year - birthYear)
def display(self):
print(self.name + "'s age is: " + str(self.age))
class Man(Person):
sex = 'Male'
man1 = Man.fromBirthYear('John', 1985)
print(isinstance(man1, Man))
man2 = Man.fromFathersAge('John', 1965, 20)
print(isinstance(man2, Man))
output
True
False
Observations:
- Using a static method to instantiate a class requires the specific instance type to be hardcoded into the method, which can lead to issues when extending a base class like
Person
to a subclass such asMan
. - The
fromFathersAge
method, being a static method, returns an instance ofPerson
and notMan
, which contradicts the principles of object-oriented programming (OOP). - On the other hand, using a class method like
fromBirthYear
adheres to OOP by taking the class itself as the first parameter and invoking the factory method accordingly, ensuring that the correct subclass instance is created.
Discover more about Python Inheritance.