Class Methods vs Static Methods in Python

In Python, both @classmethod and @staticmethod are used to define methods inside a class, but they serve different purposes. Understanding the difference between class methods and static methods is essential for writing clean and efficient object-oriented code.

Understanding Class Methods

A class method is a method that operates on the class itself rather than an instance of the class. It is defined using the @classmethod decorator and takes cls (which represents the class) as its first parameter.

Understanding Static Methods

A static method is independent of both the class and instance. It does not access or modify instance-specific data or class attributes. It is defined using the @staticmethod decorator.

Key Differences

FeatureClass MethodStatic Method
Decorator@classmethod@staticmethod
First Parametercls (class reference)No specific first parameter
Access to Class AttributesYesNo
Access to Instance AttributesNoNo
Use CaseMethods that need to work with the class itselfUtility methods that don’t require class or instance data

Examples

1. Class Method Example

In this example, we define a class method that modifies a class-level attribute.

We have a Car class with a class attribute wheels. The class method set_wheels() allows us to change the number of wheels for all instances of the class.

</>
Copy
class Car:
    wheels = 4  # Class attribute

    @classmethod
    def set_wheels(cls, num_wheels):
        """Modify the class attribute wheels."""
        cls.wheels = num_wheels

# Before modifying
print("Default wheels:", Car.wheels)

# Change the number of wheels using class method
Car.set_wheels(6)

# After modifying
print("Updated wheels:", Car.wheels)

Output:

Default wheels: 4
Updated wheels: 6

Here, Car.set_wheels(6) modifies the class attribute wheels, affecting all future instances of Car.

2. Static Method Example

Static methods do not access class attributes or instance attributes. They are just utility functions that belong to a class.

In this example, we define a convert_miles_to_km() static method that converts miles to kilometers. This function does not need to access any class-specific data.

</>
Copy
class DistanceConverter:

    @staticmethod
    def convert_miles_to_km(miles):
        """Converts miles to kilometers."""
        return miles * 1.60934

# Using static method
print("10 miles in km:", DistanceConverter.convert_miles_to_km(10))

Output:

10 miles in km: 16.0934

Here, convert_miles_to_km() simply performs a calculation and does not require any class or instance variables.

3. When to Use Class Methods vs Static Methods

Here’s an example where both class and static methods are used in the same class.

The class BankAccount has:

  • A bank_name class attribute.
  • A class method set_bank_name() to update the class attribute.
  • A static method calculate_interest() to compute interest without requiring class attributes.
</>
Copy
class BankAccount:
    bank_name = "ABC Bank"

    @classmethod
    def set_bank_name(cls, name):
        """Updates the bank name for all accounts."""
        cls.bank_name = name

    @staticmethod
    def calculate_interest(amount, rate):
        """Calculates interest given an amount and rate."""
        return amount * (rate / 100)

# Before modifying
print("Initial Bank Name:", BankAccount.bank_name)

# Update bank name using class method
BankAccount.set_bank_name("XYZ Bank")

# After modifying
print("Updated Bank Name:", BankAccount.bank_name)

# Calculate interest using static method
interest = BankAccount.calculate_interest(1000, 5)
print("Interest on $1000 at 5% rate:", interest)

Output:

Initial Bank Name: ABC Bank
Updated Bank Name: XYZ Bank
Interest on $1000 at 5% rate: 50.0

Here, set_bank_name() modifies the class-level attribute, whereas calculate_interest() performs a calculation without relying on class data.

4. Common Mistake: Using Class Method Instead of Static Method

Beginners often misuse class methods when a static method should be used. Let’s see an incorrect example.

</>
Copy
class MathOperations:
    @classmethod
    def square(cls, number):
        return number ** 2  # No need for cls here

print(MathOperations.square(4))

Since cls is not used, this should be a static method instead.

The correct code using static method is:

</>
Copy
class MathOperations:
    @staticmethod
    def square(number):
        return number ** 2

print(MathOperations.square(4))