- What are class variables — shared across all instances
- What are instance variables — unique to each instance
- Key differences — how they behave differently
- When to use each — making the right choice
- Common mistakes — what to avoid
- Best practices — writing clean, maintainable code
Understanding Variables in Classes
When you create a class in Python, you can define two types of variables: class variables and instance variables. They serve different purposes and behave differently. Understanding the distinction is essential for writing effective OOP code.
Think of it like an office building. The class variable is like the building's address — it's the same for everyone who works there. The instance variable is like each employee's desk — each person has their own, with their own things on it.
Class variables are shared by all objects of a class. Instance variables are unique to each object. This simple difference has a big impact on how your code works.
💡 Key concept: Class variables are shared across all instances. Instance variables belong to each individual object. Choose class variables for shared data, instance variables for unique data.
What are Class Variables?
Shared Data Across All Instances
A class variable is a variable that belongs to the class itself, not to any particular instance. It's defined at the class level and is shared by all objects created from that class. When you change a class variable, the change affects all instances.
Definition: A class variable is a variable defined within a class but outside any method. It is shared by all instances of the class. Class variables are often used for constants, configuration values, or data that should be the same for all objects.
# Class variables - shared across all instances
class Employee:
# Class variable - shared by all employees
company = "Tech Corp"
retirement_age = 65
total_employees = 0
def __init__(self, name, position):
# Instance variables - unique to each employee
self.name = name
self.position = position
# Access and modify class variable
Employee.total_employees += 1
def get_info(self):
return f"{self.name} works at {Employee.company} as {self.position}"
# All employees share the same company
emp1 = Employee("Alice", "Developer")
emp2 = Employee("Bob", "Designer")
print(emp1.company) # Tech Corp
print(emp2.company) # Tech Corp
print(Employee.company) # Tech Corp
# Changing the class variable affects all instances
Employee.company = "Tech Solutions"
print(emp1.company) # Tech Solutions
print(emp2.company) # Tech Solutions
# Class variables can track shared state
print(f"Total employees: {Employee.total_employees}") # 2
# Another example: Class variable for counters
class Product:
# Class variable to track next ID
next_id = 1
def __init__(self, name, price):
# Use the class variable to assign a unique ID
self.id = Product.next_id
Product.next_id += 1
self.name = name
self.price = price
def get_info(self):
return f"Product #{self.id}: {self.name} (${self.price})"
p1 = Product("Laptop", 999.99)
p2 = Product("Phone", 599.99)
p3 = Product("Tablet", 399.99)
print(p1.get_info()) # Product #1: Laptop ($999.99)
print(p2.get_info()) # Product #2: Phone ($599.99)
print(p3.get_info()) # Product #3: Tablet ($399.99)
Class variables key points:
- Shared — the same value is available to all instances
- Defined at class level — outside any method
- Accessed via class or instance — both work
- Changes affect all — modifying a class variable changes it for everyone
- Use for shared data — constants, counters, configuration
Quick Check: What is a class variable? (Answer: A variable shared by all instances of a class)
What are Instance Variables?
Unique Data for Each Object
An instance variable is a variable that belongs to a specific instance of a class. Each object has its own copy of the instance variable, with its own value. They're defined in the __init__ method using the self parameter.
Definition: An instance variable is a variable defined inside the __init__ method (or any instance method) using self. Each instance has its own copy of the variable, with its own value.
# Instance variables - unique to each object
class Student:
def __init__(self, name, grade, student_id):
# Instance variables - unique to each student
self.name = name
self.grade = grade
self.student_id = student_id
self.gpa = 0.0
self.courses = []
def add_course(self, course):
self.courses.append(course)
def set_gpa(self, gpa):
self.gpa = gpa
def get_info(self):
return f"{self.name} (ID: {self.student_id}) - Grade {self.grade}, GPA: {self.gpa}"
# Each student has their own data
alice = Student("Alice", 10, "S001")
bob = Student("Bob", 9, "S002")
charlie = Student("Charlie", 11, "S003")
# Setting data for each student independently
alice.set_gpa(3.8)
bob.set_gpa(3.2)
charlie.set_gpa(3.5)
alice.add_course("Math")
alice.add_course("Science")
bob.add_course("History")
print(alice.get_info()) # Alice (ID: S001) - Grade 10, GPA: 3.8
print(bob.get_info()) # Bob (ID: S002) - Grade 9, GPA: 3.2
print(charlie.get_info()) # Charlie (ID: S003) - Grade 11, GPA: 3.5
# Each object's data is independent
print(alice.courses) # ['Math', 'Science']
print(bob.courses) # ['History']
print(charlie.courses) # []
# Changing one object doesn't affect others
alice.grade = 11
print(alice.grade) # 11
print(bob.grade) # 9 (unchanged)
Instance variables key points:
- Unique — each instance has its own copy
- Defined with self — in __init__ or other methods
- Accessed via self — self.variable_name
- Independent — changes to one instance don't affect others
- Use for object-specific data — name, age, balance, etc.
Quick Check: What is an instance variable? (Answer: A variable that belongs to a specific instance of a class)
Class vs Instance Variables
Seeing the Difference Side by Side
Let's compare class and instance variables directly so you can see exactly how they differ in every aspect.
# Class vs Instance Variables - Side by Side
class Person:
# Class variable (shared)
species = "Homo sapiens"
planet = "Earth"
def __init__(self, name, age):
# Instance variables (unique)
self.name = name
self.age = age
# Create multiple objects
p1 = Person("Alice", 25)
p2 = Person("Bob", 30)
p3 = Person("Charlie", 35)
# 1. Class variables are shared
print("=== Class Variables (Shared) ===")
print(p1.species) # Homo sapiens
print(p2.species) # Homo sapiens
print(p3.species) # Homo sapiens
# Changing the class variable affects all instances
Person.species = "Homo sapiens sapiens"
print(p1.species) # Homo sapiens sapiens
print(p2.species) # Homo sapiens sapiens
print(p3.species) # Homo sapiens sapiens
# 2. Instance variables are unique
print("\n=== Instance Variables (Unique) ===")
print(p1.name) # Alice
print(p2.name) # Bob
print(p3.name) # Charlie
# Each instance has its own age
print(p1.age) # 25
print(p2.age) # 30
print(p3.age) # 35
# Changing one instance doesn't affect others
p1.age = 26
print(p1.age) # 26
print(p2.age) # 30 (unchanged)
# 3. Accessing class variables from the class itself
print("\n=== Accessing from the Class ===")
print(Person.species) # Homo sapiens sapiens
print(Person.planet) # Earth
# 4. Accessing instance variables from the class doesn't work
# print(Person.name) # AttributeError
| Aspect | Class Variables | Instance Variables |
|---|---|---|
| Definition | At class level, outside methods | Inside methods using self |
| Scope | Shared by all instances | Unique to each instance |
| Changes | Affects all instances | Only affects that instance |
| Access via class | Yes, ClassName.variable | No (AttributeError) |
| Access via instance | Yes, instance.variable | Yes, instance.variable |
| Use for | Shared data, constants, counters | Object-specific data |
Key insight:
- Class variables — one copy, shared by everyone
- Instance variables — one copy per object
- Choose wisely — using the wrong type can cause bugs
Quick Check: What is the main difference between class and instance variables? (Answer: Class variables are shared; instance variables are unique to each object)
Accessing and Modifying
How to Work with Both Types
Accessing and modifying class and instance variables works differently. Understanding these differences helps you avoid common mistakes.
# Accessing and modifying variables
class Config:
# Class variables
app_name = "MyApp"
version = "1.0"
debug_mode = True
def __init__(self, user_name):
# Instance variables
self.user_name = user_name
self.logged_in = False
def login(self):
self.logged_in = True
return f"{self.user_name} logged in"
def get_config(self):
# Accessing both class and instance variables
return f"{self.app_name} v{self.version} - User: {self.user_name}"
# 1. Accessing class variables
print(Config.app_name) # MyApp
print(Config.version) # 1.0
# 2. Accessing class variables from instances
c1 = Config("Alice")
c2 = Config("Bob")
print(c1.app_name) # MyApp
print(c2.app_name) # MyApp
# 3. Modifying class variables
Config.app_name = "NewApp"
print(c1.app_name) # NewApp
print(c2.app_name) # NewApp
# 4. Modifying class variables from an instance (creates an instance variable!)
c1.app_name = "CustomApp" # This creates an instance variable
print(c1.app_name) # CustomApp (instance variable)
print(c2.app_name) # NewApp (class variable)
print(Config.app_name) # NewApp (class variable - unchanged)
# 5. Modifying class variables properly
Config.debug_mode = False
print(c1.debug_mode) # False
print(c2.debug_mode) # False
# 6. Modifying instance variables
c1.logged_in = True
print(c1.logged_in) # True
print(c2.logged_in) # False
# 7. Checking for instance variables
print("Instance variable 'app_name' in c1:", hasattr(c1, 'app_name')) # True
print("Instance variable 'app_name' in c2:", hasattr(c2, 'app_name')) # False
# 8. Recommended way to access class variables
# Use the class name for clarity
class ClearExample:
class_var = "shared"
def __init__(self, value):
self.instance_var = value
def show(self):
# Access class variable via class name (clear and safe)
print(f"Class: {ClearExample.class_var}")
print(f"Instance: {self.instance_var}")
Accessing and modifying rules:
- Read class variable — via class or instance (both work)
- Modify class variable — via class name (ClassName.variable = value)
- Modify from instance — creates a new instance variable (doesn't change the class)
- Instance variables — always accessed and modified via instance
- Best practice — use ClassName.variable for class variables to avoid confusion
Quick Check: What happens if you assign a value to a class variable using an instance? (Answer: It creates a new instance variable, doesn't change the class variable)
When to Use Each
Choosing the Right Type
Knowing when to use class vs instance variables is key to writing clean code. Here are the rules of thumb to guide you.
# When to use class variables
# 1. Use class variables for shared data
class Company:
# All employees share the same company name
company_name = "Tech Corp"
headquarters = "New York"
def __init__(self, employee_name):
self.employee_name = employee_name
# 2. Use class variables for constants
class MathConstants:
PI = 3.14159
E = 2.71828
GOLDEN_RATIO = 1.61803
# 3. Use class variables for counters
class Order:
next_order_id = 1
def __init__(self, customer):
self.order_id = Order.next_order_id
Order.next_order_id += 1
self.customer = customer
# 4. Use class variables for configuration
class AppConfig:
DEBUG = True
LOG_LEVEL = "INFO"
MAX_RETRIES = 3
# When to use instance variables
# 1. Use instance variables for object-specific data
class Person:
def __init__(self, name, age, city):
# Each person has their own data
self.name = name
self.age = age
self.city = city
# 2. Use instance variables for state
class Car:
def __init__(self, make, model):
self.make = make
self.model = model
self.mileage = 0 # Each car starts with 0
self.is_running = False
# 3. Use instance variables for relationships
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self.reviews = [] # Each book has its own reviews
# Real-world example: A bank account
class BankAccount:
# Class variable: Shared interest rate
interest_rate = 0.05
def __init__(self, account_number, owner, balance=0):
# Instance variables: Unique to each account
self.account_number = account_number
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
return True
return False
# Class variable - same for all accounts
print(BankAccount.interest_rate) # 0.05
# Instance variables - different for each account
acc1 = BankAccount("A001", "Alice", 1000)
acc2 = BankAccount("A002", "Bob", 500)
print(acc1.balance) # 1000
print(acc2.balance) # 500
Decision guide:
- Class variables — use when data is shared by all instances
- Class variables — use for constants and configuration
- Class variables — use for counters and tracking
- Instance variables — use for data unique to each object
- Instance variables — use for object state
- Instance variables — use for relationships between objects
Quick Check: When should you use a class variable? (Answer: When data should be shared by all instances)
Common Mistakes
What to Watch Out For
Even experienced programmers sometimes make mistakes with class and instance variables. Here are the most common ones and how to avoid them.
# Common mistakes with class and instance variables
# Mistake 1: Using mutable class variables incorrectly
class Team:
# Class variable - shared by all teams
members = [] # Mutable class variable
def __init__(self, name):
self.name = name
def add_member(self, member):
self.members.append(member) # This adds to the class variable!
team1 = Team("Team A")
team2 = Team("Team B")
team1.add_member("Alice")
team1.add_member("Bob")
team2.add_member("Charlie")
print(team1.members) # ['Alice', 'Bob', 'Charlie'] Unexpected!
print(team2.members) # ['Alice', 'Bob', 'Charlie'] Unexpected!
# Correct approach: Use instance variable for mutable data
class FixedTeam:
def __init__(self, name):
self.name = name
self.members = [] # Instance variable
def add_member(self, member):
self.members.append(member)
team1 = FixedTeam("Team A")
team2 = FixedTeam("Team B")
team1.add_member("Alice")
team1.add_member("Bob")
team2.add_member("Charlie")
print(team1.members) # ['Alice', 'Bob'] Correct
print(team2.members) # ['Charlie'] Correct
# Mistake 2: Shadowing class variables with instance variables
class Example:
value = 10 # Class variable
def __init__(self):
self.value = 20 # Instance variable with same name
obj = Example()
print(obj.value) # 20 (instance variable)
print(Example.value) # 10 (class variable - unchanged)
# Mistake 3: Forgetting to use self for instance variables
class BadClass:
def __init__(self, name):
name = name # This creates a local variable, not an instance variable
def get_name(self):
return name # NameError
# Correct
class GoodClass:
def __init__(self, name):
self.name = name # Instance variable
def get_name(self):
return self.name
# Mistake 4: Accessing instance variables from the class
class Person:
def __init__(self, name):
self.name = name
# This doesn't work
# print(Person.name) # AttributeError
# Mistake 5: Using class variables for instance-specific data
class BadProduct:
price = 0 # Price should be an instance variable
def __init__(self, name, price):
self.name = name
# Price is still a class variable!
# Setting self.price would create an instance variable
Common mistakes to avoid:
- Mutable class variables — use instance variables for lists, dicts
- Shadowing — don't use the same name for class and instance variables
- Forgetting self — always use self for instance variables
- Wrong access — instance variables aren't accessible from the class
- Wrong type — use instance variables for object-specific data
Quick Check: What happens when you use a mutable class variable like a list? (Answer: All instances share the same list, which can cause unexpected behavior)
Best Practices
Writing Clean Code with Variables
# Best practices for class and instance variables
# 1. Use clear naming conventions
class GoodPractice:
# Class variables - UPPERCASE for constants
DEFAULT_TIMEOUT = 30
MAX_RETRIES = 3
COMPANY_NAME = "Tech Corp"
def __init__(self, name):
# Instance variables - lowercase with underscores
self.name = name
self._internal_state = False # Protected variable
def get_info(self):
return f"{self.name} at {self.COMPANY_NAME}"
# 2. Use class variables for configuration
class AppSettings:
DEBUG = False
LOG_LEVEL = "INFO"
API_ENDPOINT = "https://api.example.com"
# 3. Use class variables for counters
class UniqueID:
_next_id = 1
def __init__(self):
self.id = UniqueID._next_id
UniqueID._next_id += 1
# 4. Keep instance variables in __init__
class Person:
def __init__(self, name, age, city):
# All instance variables defined in one place
self.name = name
self.age = age
self.city = city
self.created_at = datetime.now() # Set default value
def add_hobby(self, hobby):
# Adding new instance variable outside __init__
if not hasattr(self, 'hobbies'):
self.hobbies = []
self.hobbies.append(hobby)
# 5. Use properties for controlled access
class BankAccount:
def __init__(self, balance):
self._balance = balance # Protected
@property
def balance(self):
"""Get the balance (read-only from outside)"""
return self._balance
def deposit(self, amount):
self._balance += amount
# 6. Document variable types
class User:
"""
User class with clear variable types.
Class Variables:
DEFAULT_ROLE (str): Default role for new users
MAX_USERNAME_LENGTH (int): Maximum username length
Instance Variables:
username (str): User's username
email (str): User's email address
role (str): User's role (defaults to DEFAULT_ROLE)
"""
DEFAULT_ROLE = "user"
MAX_USERNAME_LENGTH = 20
def __init__(self, username, email):
self.username = username
self.email = email
self.role = self.DEFAULT_ROLE
Best practices summary:
- Use UPPERCASE for class variable constants
- Use lowercase with underscores for instance variables
- Define instance variables in __init__
- Document your variables with docstrings
- Avoid mutable class variables — use instance variables instead
- Use properties for controlled access to instance variables
Quick Check: Where should you define instance variables? (Answer: In the __init__ method)
Try It Yourself
Experiment with class and instance variables in the editor below.
CLASS AND INSTANCE VARIABLES PRACTICE
========================================
1. CLASS VARIABLE EXAMPLE
Engineering at Tech Corp
Marketing at Tech Corp
Total employees: 2
2. INSTANCE VARIABLE EXAMPLE
Alice - Developer, Salary: $75000
Bob - Designer, Salary: $65000
3. CLASS VS INSTANCE VARIABLE
Category: Electronics (shared)
Category: Electronics (shared)
Product 1: Laptop - $999.99
Product 2: Phone - $599.99
Class and instance variables practice complete!
You've Got It!
You now understand the difference between class and instance variables. You know when to use each and how to avoid common mistakes.
Quick Quiz
Test what you've learned:
Frequently Asked Questions
What is the main difference between class and instance variables?
Can I access a class variable from an instance?
instance.class_variable). However, if you assign a value to it using the instance, it will create a new instance variable with the same name, shadowing the class variable.
What happens if I use a list as a class variable?
What's a common interview question about class vs instance variables?
Where should I define class variables?
Can I change a class variable from an instance method?
ClassName.class_variable = new_value. This is the proper way to modify class variables from methods, and it will affect all instances.
Where to Go From Here
Now that you understand class and instance variables, check out these related topics:
Inheritance
Learn how to create class hierarchies with inheritance.
Learn More →Method Overriding
Learn how to override methods in subclasses.
Learn More →Encapsulation
Learn about controlling access to data in classes.
Learn More →