Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 Beginner🔵 Advanced
Classes & ObjectsMethods & SelfInstance VariablesClass VariablesConstructors & InitializationInheritance BasicsPolymorphismEncapsulationMagic Methods & Dunder
Python/Oop/Instance Variables

💾 Instance Variables — Advanced State Management

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.


🎯 Memory Optimization with __slots__

`__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

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()}")  # None

📊 Property Validation

Use 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}")

🔄 State Tracking and Dirty Checking

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()}")

📚 Real-World Examples

Data Container with Serialization

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())

Observable Object Pattern

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..."

✅ Key Takeaways

ConceptRemember
__slots__Restrict attributes to reduce memory usage
Weak ReferenceReference without preventing garbage collection
@propertyDefine getters with validation
@setterDefine setters with business logic
State TrackingMonitor which attributes changed
Dirty CheckingDetect modifications for optimization
Memory EfficientOptimize for large numbers of instances
Computed PropertiesDerive values from other attributes

🔗 What's Next?

Continue exploring advanced OOP patterns.

Advanced: Class Variables →


Ready to practice? Try challenges or explore more concepts


Resources

Python Docs

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

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn