π·οΈ Python Class Attributes β Shared State Across Instances
π§² Introduction β Why Use Class Attributes?
In Python OOP, class attributes are attributes that are shared across all instances of a class. Unlike instance attributes (defined with self
), class attributes:
- Belong to the class itself, not to individual objects
- Are stored only once in memory
- Can be accessed or modified using either the class or any of its objects
They are useful when you want shared data or constants across all objects.
π― In this guide, you’ll learn:
- What class attributes are
- How they differ from instance attributes
- How to access and modify them
- Use cases and best practices
- Real-world examples and gotchas
β What Are Class Attributes?
A class attribute is defined inside the class but outside all methods.
class Car:
wheels = 4 # class attribute
def __init__(self, brand):
self.brand = brand # instance attribute
π Accessing Class Attributes
πΉ Using the class name:
print(Car.wheels) # 4
πΉ Using an instance:
c1 = Car("Tesla")
print(c1.wheels) # 4
π‘ Even though you’re using an object, it refers to the class attribute if no instance attribute of the same name exists.
π Modifying Class Attributes
β Change it for all instances:
Car.wheels = 6
print(c1.wheels) # 6
β οΈ Overriding with an instance attribute:
c1.wheels = 8
print(c1.wheels) # 8
print(Car.wheels) # 6 (unchanged)
π‘ When you assign c1.wheels = 8
, it creates an instance attribute that shadows the class attribute.
π Class vs Instance Attributes
Feature | Class Attribute | Instance Attribute |
---|---|---|
Defined where? | Outside methods | Inside __init__() |
Belongs to | Class | Object |
Memory | Shared | Unique per object |
Accessed by | ClassName.attr or obj.attr | self.attr |
Use case | Constants, defaults | Unique object data |
π§ͺ Real-World Example β Counting Instances
class User:
count = 0 # class attribute
def __init__(self, name):
self.name = name
User.count += 1
u1 = User("Alice")
u2 = User("Bob")
print(User.count) # 2
π‘ The count
attribute is shared and updated across all objects.
π§± Example β Shared Configuration
class Config:
debug = True
version = "1.0.0"
print(Config.debug) # True
Config.debug = False
print(Config.debug) # False
β οΈ Common Mistakes
β Mistake | β Fix |
---|---|
Modifying class attribute via object | Always modify using class name |
Assuming class attribute is unique per object | Use instance attributes for object-specific data |
Using mutable class attributes (e.g., lists) without care | Copy them in __init__ for safety |
π Best Practices
β Do This | β Avoid This |
---|---|
Use class attributes for constants or counters | Store per-object data in class attributes |
Access them via ClassName.attr for clarity | Rely on obj.attr when unsure |
Document with comments | Leave default values unexplained |
Be cautious with mutable class attributes | Use copies inside __init__ if needed |
π Summary β Recap & Next Steps
Python class attributes provide a powerful way to share common data across all instances of a class. Use them to define default values, constants, or track instance counts.
π Key Takeaways:
- β Class attributes are shared by all instances
- β Defined at the class level, outside methods
- β Modifying via instance creates a new instance variable
- β Useful for defaults, counters, and configuration flags
βοΈ Real-World Relevance:
Used in web configurations, singleton designs, ORMs, data models, and analytics counters.
β FAQ β Python Class Attributes
β Are class attributes shared across all objects?
β Yes. They are stored once and shared unless overridden in an instance.
β Can class attributes be changed?
β
Yes, using ClassName.attribute = value
. This change will reflect in all objects (unless overridden).
β Can class attributes be accessed using self
?
β
Yes, but it’s better to use ClassName.attr
for clarity when modifying them.
β What happens if I modify a class attribute using an instance?
β It creates an instance attribute, not modifying the class one. Always update using the class name.
β Should I store mutable defaults in class attributes?
β οΈ Be careful. Shared mutable objects like lists/dicts can cause unexpected behavior across instances. Prefer creating a fresh copy in __init__()
.
Share Now :