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
Feature | Class Method | Static Method |
---|---|---|
Decorator | @classmethod | @staticmethod |
First Parameter | cls (class reference) | No specific first parameter |
Access to Class Attributes | Yes | No |
Access to Instance Attributes | No | No |
Use Case | Methods that need to work with the class itself | Utility 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.
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.
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.
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.
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:
class MathOperations:
@staticmethod
def square(number):
return number ** 2
print(MathOperations.square(4))