Python classmethod()

Python classmethod() is a special type of method that's bound to the class and not its instance. You create a class method using the @classmethod decorator, and it automatically receives the class itself as its first argument, conventionally named cls.
Table of Contents

Understanding Python classmethod()

In Python, a class method is a special type of method that is bound to the class and not its instance. You create a class method using the @classmethod decorator. The most important feature of a Python class method() is that it receives the class itself as the first argument, conventionally named cls. This allows the method to access and modify class-level data or perform other operations relevant to the class as a whole. They can’t modify the object instance state.

Syntax of Python classmethod()

class MyClass:
    @classmethod
    def my_class_method(cls, arg1, arg2):
        # Method body

Explanation

  • class MyClass:: Defines a class named MyClass.
  • @classmethod: Decorator that marks the following method as a class method.
  • def my_class_method(cls, arg1, arg2):: Defines the class method.
  • cls: First argument to the class method, representing the class itself. It is similar to self for instance methods, but cls refers to class.
  • arg1, arg2: Regular arguments that the class method can accept.
  • # Method body: This is where you write the code that the class method will execute.

Example of Python classmethod()

class Employee:
    num_of_employees = 0

    def __init__(self, name):
        self.name = name
        Employee.num_of_employees += 1

    @classmethod
    def get_count(cls):
        return cls.num_of_employees

print(Employee.get_count())
emp1 = Employee("Alice")
print(Employee.get_count())

Explanation

  • class Employee:: Defines a class named Employee.
  • num_of_employees = 0: Initializes a class-level variable to keep track of the number of employees.
  • def __init__(self, name):: This is the constructor for the class.
  • self.name = name: Initializes an instance variable name.
  • Employee.num_of_employees += 1: Increments the num_of_employees counter each time an Employee object is created.
  • @classmethod: Decorator marks the get_count method as a class method.
  • def get_count(cls):: Defines the class method get_count, which takes the class itself as the first argument (cls).
  • return cls.num_of_employees: Returns the current value of the class variable num_of_employees.
  • print(Employee.get_count()): Calls the class method get_count directly on the Employee class and prints the result.
  • emp1 = Employee("Alice"): Creates an instance of the Employee class.
  • print(Employee.get_count()): Again calls get_count after an employee object has been created.

Output

0
1


classmethod() Parameters

A class method, created using the @classmethod decorator, always takes the class itself as its first parameter. This parameter is conventionally named cls, but you can technically use any valid variable name (though it’s strongly recommended to stick with cls for readability). After the cls parameter, a Python classmethod can accept any number of other arguments, just like a regular method. These additional parameters can be used to pass data to the class method.

Syntax

class MyClass:
    @classmethod
    def my_method(cls, param1, param2, ...):
        # Method body

Example

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    @classmethod
    def square(cls, side):
        return cls(side, side)

my_square = Rectangle.square(5)
print(my_square.width)
print(my_square.height)

Explanation

  • class Rectangle:: Defines a class named Rectangle.
  • def __init__(self, width, height):: Constructor for Rectangle.
  • self.width = width: Initializes the width attribute of the Rectangle instance.
  • self.height = height: Initializes the height attribute of the Rectangle instance.
  • @classmethod: Decorator marks the square method as a class method.
  • def square(cls, side):: Defines the class method square, which takes the class (cls) and side as parameters.
  • return cls(side, side): Creates and returns a new Rectangle object with equal width and height.
  • my_square = Rectangle.square(5): Calls the class method square on the Rectangle class to create a square with side length 5.
  • print(my_square.width): Prints the width of the created square.
  • print(my_square.height): Prints the height of the created square.

Output

5
5


classmethod() Return Value

Python classmethod() can return any value, such as a regular function or method. What the method returns depends on what you’ve programmed it to do. It could return a new class instance, a calculated value, a string, or even None if you don’t explicitly return anything. The important thing to remember is that the return value is associated with the class, not a specific instance of the class because class methods operate at the class level.

Example

class MathUtils:
    @classmethod
    def add(cls, x, y):
        return x + y

result = MathUtils.add(10, 20)
print(result)

Explanation

  • class MathUtils:: Defines a class named MathUtils.
  • @classmethod: Decorator marks add as a class method.
  • def add(cls, x, y):: Defines the class method add.
  • return x + y: Returns the sum of x and y.
  • result = MathUtils.add(10, 20): Calls the add method on the MathUtils class and stores the result in result.
  • print(result): Prints the value of result, which is 30.

Output

30


Class Method vs Static Method

In Python, both class and static methods are associated with a class but work differently. A class method receives the class itself as the first argument (conventionally named cls), while a static method doesn’t receive any special first argument. This means a class method can access and modify class-level data while a static method can’t. Static methods are essentially like regular functions that happen to be defined inside a class and don’t have access to cls or self. They are used to group logically related functions inside a class for better organization.

Syntax

class MyClass:
    @classmethod
    def my_class_method(cls, ...):
        # Class method body

    @staticmethod
    def my_static_method(...):
        # Static method body

Explanation

  • class MyClass:: Defines a class named MyClass.
  • @classmethod: Decorator marks my_class_method as a class method.
  • def my_class_method(cls, ...):: Defines the class method, which takes the class cls as the first argument.
  • # Class method body: This is where you write the code for the class method.
  • @staticmethod: Decorator marks my_static_method as a static method.
  • def my_static_method(...):: Defines the static method, which does not take cls or self as an argument.
  • # Static method body: This is where you write the code for the static method.

Example

class MyClass:
    class_var = "I am a class variable"

    @classmethod
    def class_method(cls):
        print(f"Class method called for {cls.__name__}")
        print(cls.class_var)

    @staticmethod
    def static_method():
        print("Static method called")

MyClass.class_method()
MyClass.static_method()

Explanation

  • class MyClass:: Defines a class named MyClass.
  • class_var = "I am a class variable": Initializes a class-level variable.
  • @classmethod: Marks class_method as a class method.
  • def class_method(cls):: Defines the class method class_method.
  • print(f"Class method called for {cls.__name__}"): Prints the name of the class.
  • print(cls.class_var): Accesses and prints the class variable class_var.
  • @staticmethod: Marks static_method as a static method.
  • def static_method():: Defines the static method static_method.
  • print("Static method called"): Prints a message.
  • MyClass.class_method(): Calls the class method on MyClass.
  • MyClass.static_method(): Calls the static method on MyClass.

Output

Class method called for MyClass
I am a class variable
Static method called


Create a Simple classmethod without Python classmethod()

Usually, you’d use the @classmethod decorator to create a class method. However, to avoid the decorator, you can use the classmethod() function to achieve a similar result. You define a regular function and then pass it to classmethod() function. This approach is less common and readable, but it demonstrates that decorators are essentially “syntactic sugar” that makes your code cleaner and more intuitive. In this case, you must pass the function name to classmethod() function.

Syntax

class MyClass:
    def my_method(cls, ...):
        # Method body
    my_method = classmethod(my_method)

Explanation

  • class MyClass:: Defines a class named MyClass.
  • def my_method(cls, ...):: Defines a regular method that you intend to make into a class method.
  • # Method body: This is where you write the code for the method.
  • my_method = classmethod(my_method): Converts my_method into a class method using the classmethod() function.

Example

class Dog:
    species = "Canis familiaris"

    def describe(cls):
        print(f"Dogs belong to the species {cls.species}")

Dog.describe = classmethod(Dog.describe)
Dog.describe()

Explanation

  • class Dog:: Defines a class named Dog.
  • species = "Canis familiaris": Initializes a class-level variable species.
  • def describe(cls):: Defines a method describe that will be converted into a class method.
  • print(f"Dogs belong to the species {cls.species}"): Prints the species of the dog, accessing the class variable species.
  • Dog.describe = classmethod(Dog.describe): Converts the describe method into a class method using classmethod().
  • Dog.describe(): Calls the class method describe on the Dog class.

Output

Dogs belong to the species Canis familiaris


How the Class Method Works for the Inheritance?

In Python, class methods participate in inheritance, meaning they can be called subclasses and overridden in subclasses. When a class method is called on a subclass, the subclass itself is passed as the cls argument. This allows class methods for polymorphic behavior at the class level. If a subclass overrides a class method, the subclass’s version of the method will be called, but it will still receive the subclass as its first argument.

Syntax

class Parent:
    @classmethod
    def my_method(cls):
        # Parent class method body

class Child(Parent):
    @classmethod
    def my_method(cls):
        # Child class method body

Explanation

  • class Parent:: Defines a parent class named Parent.
  • @classmethod: Decorator marks my_method in the parent class as a class method.
  • def my_method(cls):: Defines the parent’s class method, which takes cls (the class) as its first argument.
  • # Parent class method body: Code for the parent’s class method goes here.
  • class Child(Parent):: Defines a child class named Child that inherits from Parent.
  • @classmethod: Decorator marks my_method in the child class as a class method.
  • def my_method(cls):: Defines the child’s class method, which also takes cls (the class) as its first argument.
  • # Child class method body: The code for the child’s class method goes here.

Example

class Animal:
    @classmethod
    def make_sound(cls):
        print(f"A generic {cls.__name__} sound")

class Cat(Animal):
    @classmethod
    def make_sound(cls):
        print(f"Meow! I'm a {cls.__name__}")

Animal.make_sound()
Cat.make_sound()

Explanation

  • class Animal:: Defines a parent class named Animal.
  • @classmethod: Decorator marks make_sound in Animal as a class method.
  • def make_sound(cls):: Defines the class method make_sound for Animal.
  • print(f"A generic {cls.__name__} sound"): Prints a generic sound message, using cls.__name__ to refer to the class name.
  • class Cat(Animal):: Defines a Cat class that inherits from Animal.
  • @classmethod: Decorator marks make_sound in Cat as a class method.
  • def make_sound(cls):: Defines the class method make_sound for Cat, overriding the parent’s method.
  • print(f"Meow! I'm a {cls.__name__}"): Prints a specific sound message for Cat.
  • Animal.make_sound(): Calls the class method make_sound on the Animal class.
  • Cat.make_sound(): Calls the class method make_sound on the Cat class.

Output

A generic Animal sound
Meow! I’m a Cat


Factory Method Using Class Method

A factory method is a creational design pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. In Python, you can implement a factory method using a Python class method. The class method acts as a factory that can create and return class instances. This is especially useful when the object creation logic is complex, or you want to return different subclasses based on different inputs.

Syntax

class MyClass:
    def __init__(self, ...):
        # Constructor body

    @classmethod
    def create_object(cls, ...):
        # Logic to create and return an instance of MyClass
        return cls(...)

Explanation

  • class MyClass:: Defines a class named MyClass.
  • def __init__(self, ...):: Constructor for MyClass, initializing new instances.
  • # Constructor body: Code to initialize the object’s attributes goes here.
  • @classmethod: Decorator marks create_object as a class method, making it a factory method.
  • def create_object(cls, ...):: Defines the factory method, which takes cls (the class) as its first argument.
  • # Logic to create and return an instance of MyClass: This is where you write the code to set up the new object.
  • return cls(...): Creates and returns a new instance of MyClass (or a subclass), using cls to refer to the class.

Example

class DataProcessor:
    def __init__(self, data):
        self.data = data

    @classmethod
    def from_string(cls, data_string, delimiter):
        data = data_string.split(delimiter)
        return cls(data)

processor = DataProcessor.from_string("apple,banana,cherry", ",")
print(processor.data)

Explanation

  • class DataProcessor:: Defines a class named DataProcessor.
  • def __init__(self, data):: Constructor for DataProcessor, taking data as an argument.
  • self.data = data: Initializes the data attribute of the DataProcessor instance.
  • @classmethod: Decorator marks from_string as a class method and a factory method.
  • def from_string(cls, data_string, delimiter):: Defines the factory method from_string.
  • data = data_string.split(delimiter): Splits the input string into a list using the provided delimiter.
  • return cls(data): Creates and returns a new DataProcessor instance, passing the processed data to the constructor.
  • processor = DataProcessor.from_string("apple,banana,cherry", ","): Calls the from_string factory method to create a DataProcessor object.
  • print(processor.data): Prints the data attribute of the DataProcessor object.

Output

[‘apple’, ‘banana’, ‘cherry’]


Accessing Class-Level Data using Class Method

Class methods are often used to access or modify class-level data, which is shared across all class instances. Since a Python classmethod() receives the class itself as its first argument (conventionally named cls), you can use cls to reference class-level variables and other class attributes. This allows you to interact with data associated with the class rather than specific instances.

Syntax

class MyClass:
    class_variable = ...

    @classmethod
    def my_method(cls, ...):
        # Access or modify cls.class_variable

Explanation

  • class MyClass:: Defines a class named MyClass.
  • class_variable = ...: Initializes a class-level variable.
  • @classmethod: Decorator marks my_method as a class method.
  • def my_method(cls, ...):: Defines the class method my_method, with cls as the first argument.
  • # Access or modify cls.class_variable: Inside the method, you can use cls.class_variable to access or change the class-level data.

Example

class Counter:
    count = 0

    @classmethod
    def increment(cls):
        cls.count += 1

    @classmethod
    def get_count(cls):
        return cls.count

Counter.increment()
Counter.increment()
print(Counter.get_count())

Explanation

  • class Counter:: Defines a class named Counter.
  • count = 0: Initializes a class-level variable count to 0.
  • @classmethod: Decorator marks increment as a class method.
  • def increment(cls):: Defines the class method increment.
  • cls.count += 1: Increments the class-level variable count.
  • @classmethod: Decorator marks get_count as a class method.
  • def get_count(cls):: Defines the class method get_count.
  • return cls.count: Returns the current value of count.
  • Counter.increment(): Calls the increment method to increase count.
  • Counter.increment(): Calls increment again.
  • print(Counter.get_count()): Calls get_count to retrieve and print the current count.

Output

2


Conclusion

Python classmethod() provides a way to define methods that operate on the class itself rather than on class instances. Using the @classmethod decorator, you can create methods that receive the class as their first argument, conventionally named cls. Class methods are useful for factory methods, accessing or modifying class-level data, and interacting with subclasses during inheritance. They offer a powerful tool for organizing and structuring your code in an object-oriented way, especially when dealing with operations that concern the class as a whole rather than specific instances. Understanding when and how to use Python classmethod is an important aspect of mastering Python’s object-oriented programming features.


Also Read

Python compile()

Python complex()


Python Reference

python classmethod()

Table of Contents