Skip to main content

Python classmethod() Function

The classmethod() function returns a class method for the given function.

Syntax

classmethod(function)
danger

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:

ParameterConditionDescription
functionRequiredFunction 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() and printHeight() take a single parameter cls and not self (as in usual classes).
  • The method Person.printAge is passed as an argument to the function classmethod. 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 and printHeight without creating a Person object, and so you can print the class variables age and height.

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 as Man.
  • The fromFathersAge method, being a static method, returns an instance of Person and not Man, 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.
note

Discover more about Python Inheritance.