In Python, classes are the foundation of object-oriented programming (OOP). They allow you to bundle data and functionality together, making code reusable, scalable, and easier to maintain. Understanding class attributes and methods is a key step for anyone learning Python OOP concepts.
In this tutorial, we will learn what class attributes and methods are, how they differ from instance attributes and methods, and how to use them effectively with examples. Let’s dive in!

What Are Class Attributes?
Class attributes are variables that are shared across all instances of a class. They are defined directly inside the class, but outside of any methods. Since they belong to the class itself, all objects of that class will share the same value unless it is overridden by an instance.
Example of Class Attributes
class Car:
# Class attribute
wheels = 4
def __init__(self, brand, color):
# Instance attributes
self.brand = brand
self.color = color
# Creating instances
car1 = Car("Toyota", "Red")
car2 = Car("Honda", "Blue")
print(f"Car1 brand: {car1.brand}, Wheels: {car1.wheels}")
print(f"Car2 brand: {car2.brand}, Wheels: {car2.wheels}")
# Access class attribute directly
print(f"All cars have {Car.wheels} wheels.")
In this example, wheels is a class attribute. Both car1 and car2 share the same value of 4 wheels. If you change the class attribute value, it will affect all instances that have not overridden it.
Modifying Class Attributes
Car.wheels = 6
print(f"Car1 wheels after change: {car1.wheels}")
print(f"Car2 wheels after change: {car2.wheels}")
After updating Car.wheels to 6, both car1 and car2 reflect this change, because the attribute belongs to the class, not to the individual objects.
What Are Instance Attributes?
Instance attributes belong to each object individually. They are created using the self keyword inside the constructor (__init__ method). Each object can have its own value for these attributes.
Example of Instance Attributes
class Dog:
species = "Canine" # Class attribute
def __init__(self, name, age):
self.name = name # Instance attribute
self.age = age # Instance attribute
dog1 = Dog("Buddy", 3)
dog2 = Dog("Charlie", 5)
print(f"{dog1.name} is {dog1.age} years old and is a {dog1.species}.")
print(f"{dog2.name} is {dog2.age} years old and is a {dog2.species}.")
Here, species is shared by all dogs, but each dog has its own name and age.
Class Methods
Class methods are methods that are bound to the class rather than its instances. They can modify the class state that applies across all instances. To define a class method, use the @classmethod decorator and pass cls as the first parameter instead of self.
Example of Class Methods
class Employee:
company_name = "TechCorp"
def __init__(self, name, position):
self.name = name
self.position = position
@classmethod
def change_company(cls, new_name):
cls.company_name = new_name
emp1 = Employee("Alice", "Manager")
emp2 = Employee("Bob", "Developer")
print(f"Before change: {emp1.company_name}, {emp2.company_name}")
# Using class method to update
Employee.change_company("NextGenTech")
print(f"After change: {emp1.company_name}, {emp2.company_name}")
The change_company class method updates the class attribute for all instances. Notice that the change affects both emp1 and emp2.
Static Methods
Static methods are methods that don’t modify the class or instance state. They are used when you need a utility function that belongs logically to the class but doesn’t need to access self or cls. You define them with the @staticmethod decorator.
Example of Static Methods
class MathUtils:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
print(MathUtils.add(5, 3))
print(MathUtils.multiply(4, 2))
Static methods can be called using the class name directly without creating an instance.
Summary: Differences Between Attributes and Methods
| Type | Description | Keyword |
|---|---|---|
| Class Attribute | Shared by all instances of the class | Defined directly inside the class |
| Instance Attribute | Unique to each instance | Defined with self in __init__ |
| Class Method | Modifies class-level data | @classmethod, uses cls |
| Static Method | Utility function; no access to class or instance | @staticmethod |
Real-World Example
Let’s put everything together in a simple real-world example.
class BankAccount:
bank_name = "Global Bank"
interest_rate = 0.02
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
print(f"{self.owner} deposited ${amount}. New balance: ${self.balance}")
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
print(f"{self.owner} withdrew ${amount}. Remaining balance: ${self.balance}")
else:
print("Insufficient funds!")
@classmethod
def update_interest_rate(cls, new_rate):
cls.interest_rate = new_rate
print(f"Updated interest rate to {cls.interest_rate * 100}%")
@staticmethod
def bank_policy():
return "All accounts must maintain a minimum balance of $100."
# Create objects
acc1 = BankAccount("Alice", 500)
acc2 = BankAccount("Bob", 1000)
acc1.deposit(200)
acc2.withdraw(300)
BankAccount.update_interest_rate(0.03)
print(BankAccount.bank_policy())
In this program:
bank_nameandinterest_rateare class attributes.depositandwithdraware instance methods.update_interest_rateis a class method that updates the class-wide rate.bank_policyis a static method used as a utility function.
Conclusion
Understanding Python’s class attributes and methods is essential for mastering object-oriented programming. Class attributes define shared characteristics, instance attributes define individual properties, and methods define behaviors. By combining these effectively, you can design robust and reusable programs.
Whether you are building small scripts or large-scale applications, mastering these OOP fundamentals will make your Python code cleaner and more efficient.