Difficulty: Intermediate
What is the difference between @classmethod and @staticmethod in Python?
@classmethod: receives the class as the first argument (cls instead of self). Can access and modify class state. Used for alternative constructors and factory methods.
@staticmethod: receives no implicit first argument. Cannot access class or instance state. Used for utility functions logically grouped with the class but not needing class/instance access.
Regular method: receives the instance (self). Can access both instance and class state.
When to use: - classmethod: alternative constructors, factory methods, class-level state - staticmethod: helper functions that do not need class or instance
from datetime import date
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def from_birth_year(cls, name, birth_year):
"""Alternative constructor."""
age = date.today().year - birth_year
return cls(name, age) # cls is Person (or subclass!)
@classmethod
def from_dict(cls, data):
return cls(data['name'], data['age'])
@staticmethod
def validate_age(age):
"""Utility - no need for cls or self."""
return 0 <= age <= 150
def __repr__(self):
return f'Person(name={self.name!r}, age={self.age})'
p1 = Person('Alice', 30)
p2 = Person.from_birth_year('Bob', 1995)
p3 = Person.from_dict({'name': 'Charlie', 'age': 25})
print(p1, p2, p3)
print(Person.validate_age(200)) # False
# classmethod with inheritance
class Employee(Person):
pass
e = Employee.from_birth_year('Dave', 1990)
print(type(e)) # <class 'Employee'> - cls is Employee!
cls is the class itself (or subclass). When called on Employee, cls is Employee - classmethod constructors preserve polymorphism.
class MathHelper:
# Regular method: needs instance
def double(self, x):
return x * 2
# classmethod: creates instance, modifies class state
@classmethod
def create_with_multiplier(cls, multiplier):
obj = cls()
obj._multiplier = multiplier
return obj
# staticmethod: pure utility, no cls/self needed
@staticmethod
def is_even(n):
return n % 2 == 0
@staticmethod
def gcd(a, b):
while b:
a, b = b, a % b
return a
print(MathHelper.is_even(4)) # True
print(MathHelper.gcd(48, 18)) # 6
# Calling on instance is also valid
m = MathHelper()
print(m.is_even(7)) # False (still works)
print(m.gcd(100, 75)) # 25
# Comparison summary
class Demo:
class_var = 'shared'
def instance_method(self):
return self # Has access to instance
@classmethod
def class_method(cls):
return cls # Has access to class
@staticmethod
def static_method():
return 'no access to cls or self'
staticmethod is a plain function with namespace. classmethod gets the class. Regular method gets the instance. All three can be called on instances.
classmethod, staticmethod, cls, Factory Methods, Alternative Constructors