
Python
Advanced instance variable handling includes memory optimization with `__slots__`, weak references for circular dependency prevention, and sophisticated state tracking patterns. These techniques are essential for large-scale applications.
`__slots__` restricts which attributes an object can have, reducing memory overhead significantly. Useful for classes with many instances.
# Without __slots__ - uses __dict__
class PersonStandard:
def __init__(self, name, age):
self.name = name
self.age = age
# With __slots__ - more memory efficient
class PersonOptimized:
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
# Benchmark memory usage
import sys
p1 = PersonStandard("Alice", 25)
p2 = PersonOptimized("Alice", 25)
print(f"Standard: {sys.getsizeof(p1.__dict__)} bytes") # Uses __dict__
print(f"Optimized: No __dict__ - more memory efficient")
# With __slots__, can't add arbitrary attributes
try:
p2.email = "alice@example.com" # Error!
except AttributeError as e:
print(f"Error: {e}")Weak references don't prevent garbage collection, solving circular dependency issues where objects reference each other.
import weakref
class Parent:
def __init__(self, name):
self.name = name
self.children = []
def add_child(self, child):
self.children.append(child)
child.parent = weakref.ref(self) # Weak reference
class Child:
def __init__(self, name):
self.name = name
self.parent = None
def get_parent(self):
if self.parent is None:
return None
return self.parent() # Dereference weak reference
parent = Parent("John")
child = Child("Sarah")
parent.add_child(child)
print(f"Parent: {child.get_parent().name}")
# Weak reference doesn't prevent garbage collection
del parent # Parent can be garbage collected
print(f"Parent after del: {child.get_parent()}") # NoneUse properties with setters for sophisticated validation and computed attributes.
class Temperature:
def __init__(self, celsius):
self._celsius = None
self.celsius = celsius # Use setter
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
if not isinstance(value, (int, float)):
raise TypeError("Temperature must be numeric")
if value < -273.15:
raise ValueError("Below absolute zero")
self._celsius = value
@property
def fahrenheit(self):
"""Computed property"""
return (self._celsius * 9/5) + 32
@fahrenheit.setter
def fahrenheit(self, value):
self.celsius = (value - 32) * 5/9
@property
def kelvin(self):
"""Read-only computed property"""
return self._celsius + 273.15
temp = Temperature(20)
print(f"Celsius: {temp.celsius}")
print(f"Fahrenheit: {temp.fahrenheit}")
print(f"Kelvin: {temp.kelvin}")
temp.fahrenheit = 68 # Set via different property
print(f"After F change: {temp.celsius}")Track which attributes have changed, useful for ORM systems and caching.
class TrackedObject:
def __init__(self):
self._original_state = {}
self._current_state = {}
def __setattr__(self, name, value):
if name.startswith('_'):
super().__setattr__(name, value)
else:
if not hasattr(self, '_current_state'):
self.__dict__['_current_state'] = {}
self._current_state[name] = value
super().__setattr__(name, value)
def save_state(self):
"""Save current state as original"""
self._original_state = self._current_state.copy()
def get_changes(self):
"""Get attributes that changed"""
changes = {}
for key, value in self._current_state.items():
if key not in self._original_state or self._original_state[key] != value:
changes[key] = value
return changes
def is_dirty(self):
"""Check if object has changes"""
return len(self.get_changes()) > 0
class User(TrackedObject):
def __init__(self, name, email):
super().__init__()
self.name = name
self.email = email
self.save_state()
user = User("Alice", "alice@example.com")
print(f"Dirty: {user.is_dirty()}")
user.email = "alice.new@example.com"
print(f"Dirty: {user.is_dirty()}")
print(f"Changes: {user.get_changes()}")import json
class DataContainer:
__slots__ = ('_data', '_metadata')
def __init__(self, **kwargs):
self._data = kwargs
self._metadata = {
'created': True,
'modified': False
}
def __getattr__(self, name):
if name.startswith('_'):
return object.__getattribute__(self, name)
return self._data.get(name)
def __setattr__(self, name, value):
if name.startswith('_'):
super().__setattr__(name, value)
else:
if not hasattr(self, '_data'):
object.__setattr__(self, '_data', {})
self._data[name] = value
if hasattr(self, '_metadata'):
self._metadata['modified'] = True
def to_dict(self):
return self._data.copy()
def to_json(self):
return json.dumps(self._data)
container = DataContainer(name="Project", version="1.0")
container.description = "A sample project"
print(container.name)
print(container.to_dict())class Observable:
def __init__(self):
self._observers = []
self._state = {}
def attach(self, observer):
"""Register observer"""
self._observers.append(observer)
def detach(self, observer):
"""Unregister observer"""
self._observers.remove(observer)
def notify(self, attribute, value):
"""Notify observers of state change"""
for observer in self._observers:
observer.update(attribute, value)
def __setattr__(self, name, value):
if name.startswith('_'):
super().__setattr__(name, value)
else:
super().__setattr__(name, value)
if hasattr(self, '_observers'):
self.notify(name, value)
class Observer:
def __init__(self, name):
self.name = name
def update(self, attribute, value):
print(f"{self.name}: {attribute} changed to {value}")
class Document(Observable):
def __init__(self, title):
super().__init__()
self.title = title
self.content = ""
doc = Document("Report")
observer = Observer("Logger")
doc.attach(observer)
doc.title = "Annual Report"
doc.content = "Financial data..."| Concept | Remember |
|---|---|
| __slots__ | Restrict attributes to reduce memory usage |
| Weak Reference | Reference without preventing garbage collection |
| @property | Define getters with validation |
| @setter | Define setters with business logic |
| State Tracking | Monitor which attributes changed |
| Dirty Checking | Detect modifications for optimization |
| Memory Efficient | Optimize for large numbers of instances |
| Computed Properties | Derive values from other attributes |
Continue exploring advanced OOP patterns.
Ready to practice? Try challenges or explore more concepts
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward