Python OOP Gotcha: Mutable Class Variables

The Subtle Danger of Mutable Class Variables in Python One of the most common — and surprisingly tricky — mistakes in Python OOP is using mutable class variables. Consider this example: class ShoppingCart: items = [] # ❌ Mutable class variable def add_item(self, item): self.items.append(item) cart1 = ShoppingCart() cart2 = ShoppingCart() cart1.add_item("Laptop") print(cart1.items) # ['Laptop'] print(cart2.items) # ['Laptop'] Why does cart2 contain "Laptop" even though we never added anything to it? Because items is defined at the class level, not the instance level. And since lists are mutable, every instance shares the same underlying object. This isn’t a bug in Python. It’s how attribute lookup works: • Python first checks the instance. • If not found, it checks the class. • Mutable class attributes are shared across all instances. ⸻ The Correct Approach Initialize mutable data inside __init__: class ShoppingCart: def __init__(self): self.items = [] # ✅ Instance-specific list def add_item(self, item): self.items.append(item) Now each object has its own independent list. ⸻ Rule of Thumb Use class variables for: • Constants • Shared configuration • Intentionally shared state Avoid them for: • Lists • Dictionaries • Sets • Any mutable structure meant to be instance-specific Small oversight. Big debugging session. Understanding how Python handles attribute resolution prevents subtle shared-state bugs that can be painful to trace in production systems. #Python #OOP #SoftwareEngineering #BackendDevelopment #CleanCode

To view or add a comment, sign in

Explore content categories