All Courses
Object-Oriented Programming

Python Class Methods & Class Attributes

Instance vs Class: The Key Distinction

Instance Class
Associated with A specific object The class itself
Keyword self cls
Needs an instance to access? Yes No
Shared across all instances? No Yes

Class Attributes

A class attribute is defined directly inside the class body — not inside any method and not prefixed with self.

class Car:
    number_of_cars = 0       # class attribute
    wheels = 4               # class attribute

    def __init__(self, make, model):
        self.make = make     # instance attribute
        self.model = model   # instance attribute

Accessing Class Attributes

# Via the class (preferred)
print(Car.number_of_cars)   # 0

# Via an instance (works, but not preferred)
c1 = Car("Ford", "Edge")
print(c1.number_of_cars)    # 0

Modifying a Class Attribute

Car.number_of_cars += 3
print(Car.number_of_cars)   # 3

⚠️ If you assign via an instance (c1.number_of_cars = 1), Python creates a new instance attribute on that object — it does NOT modify the class attribute.

Tracking Instance Count with a Class Attribute

class Car:
    number_of_cars = 0

    def __init__(self, make, model):
        self.make = make
        self.model = model
        Car.number_of_cars += 1   # update class attribute on every new instance

c1 = Car("Ford", "Edge")
c2 = Car("Mazda", "3")
print(Car.number_of_cars)   # 2

When to Use a Class Attribute

Use a class attribute when the value is: - The same for every instance (e.g. all cars have 4 wheels) - Shared and updated across all instances (e.g. a running count)

Use an instance attribute for anything specific to one object (e.g. make, model).


Class Methods

A class method acts on the class itself, not on any instance. It is defined with the @classmethod decorator and takes cls (the class) as its first parameter instead of self.

class Car:
    number_of_cars = 0

    @classmethod
    def update_number_of_cars(cls, cars):
        cls.number_of_cars = cars

Calling a Class Method

# Via the class (preferred)
Car.update_number_of_cars(10)

# Via an instance (works, but cls still refers to Car — not the instance)
c1 = Car("Ford", "Edge")
c1.update_number_of_cars(10)

Rules for Class Methods

  • Always use @classmethod decorator above the definition
  • First parameter is always cls (stands for the class — like self but for the class)
  • cls is a hidden parameter — passed automatically, just like self
  • Can only access class attributes and other class methods
  • ❌ Cannot access instance attributes (self.make, self.model, etc.) — there's no instance context

Practical Example — Circle Class

A common use case: grouping related utility methods together under one class, with a shared class attribute.

class Circle:
    pi = 3.14    # class attribute — change once, updates all methods

    @classmethod
    def area(cls, radius):
        return cls.pi * radius ** 2

    @classmethod
    def perimeter(cls, radius):
        return 2 * cls.pi * radius

    @classmethod
    def get_area_and_perimeter(cls, radius):
        return cls.area(radius), cls.perimeter(radius)

Usage

print(Circle.area(2))                        # 12.56
print(Circle.perimeter(4))                   # 25.12
print(Circle.get_area_and_perimeter(4))      # (50.24, 25.12)

No instances needed — everything works directly on the class.

Why Group Methods in a Class Like This?

  • All related logic is in one place
  • One change to pi updates every method automatically
  • Class methods can call other class methods cleanly via cls

Key Takeaways & Recap

Concept Summary
Class attribute Defined in the class body, no self; shared by all instances
Instance attribute Defined with self; unique to each object
@classmethod Decorator that marks a method as a class method
cls Refers to the class itself (not an instance)
Access rule Class methods can only use class-level attributes and methods
Preferred access Use ClassName.attribute / ClassName.method() for class-level things