@classmethod is a decorator in Python used to define class methods. Class methods are bound to the class rather than the instance and can be called through either the class or an instance.

Basic usage:

class MyClass:
	
	def __init__(self):
		self.x = 0
	
	@classmethod
	def my_class_method(cls):
		pass

	
MyClass.my_class_method()

obj = MyClass()
obj.my_class_method()

Methods decorated with @classmethod have the following characteristics:

  • The first parameter is cls (a common convention, short for class), which refers to the class itself rather than the instance;
  • Can be called through either the class or an instance - in this example, you can use either MyClass.my_class_method() or obj.my_class_method();
  • Cannot access instance attributes;

Class methods are aware of which class they're called from during inheritance:

class Parent:
	
    @classmethod
    def class_method(cls):
        print(f"Class method in {cls.__name__}")
		
		
class Child(Parent):
    pass

Parent.class_method()  # Output: Class method in Parent
Child.class_method()   # Output: Class method in Child

Common Use Cases for @classmethod

1. Alternative Constructors

class Integer:
	
    def __init__(self, value):
        self.value = value
    
    @classmethod
    def from_str(cls, str_value):
		
        if str_value == 'six':
            return cls(6) #Equivalent to return Integer(6)
		
        pass
	
        return Integer(0)
    
    def __str__(self):
        return str(self.value)

# Standard constructor
int1 = Integer(1)

# Using class method as an alternative constructor
int2 = Integer.from_str("six")

2. Accessing and Modifying Class State

class Counter:
	
    count = 0  # Class variable
    
    def __init__(self):
        Counter.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count

print(Counter.get_count())  # 0

for i in range(10):
	_ = Counter()

print(Counter.get_count())  # 10