💡 Advanced Python Concepts
Estimated reading: 4 minutes 23 views

🔍 Python Object Internals – Understand How Python Objects Work Under the Hood

🧲 Introduction – Why Learn Python Object Internals?

Every value in Python—whether it’s an integer, string, function, or class—is an object. Understanding the internal structure of Python objects helps you:

  • Write efficient and memory-safe code
  • Understand attribute lookups and method resolution
  • Debug complex issues in OOP, metaclasses, and descriptors
  • Master Python at a deeper, more professional level

Whether you’re working on performance, design patterns, or frameworks—object internals are the foundation of Python programming.

🎯 In this guide, you’ll learn:

  • What Python objects are made of
  • How attributes are stored and accessed
  • Special internal attributes (__dict__, __slots__, __class__)
  • Memory layout and object identity
  • Inheritance and method resolution order (MRO)

✅ Everything Is an Object in Python

print(type(42))            # <class 'int'>
print(type("Hello"))       # <class 'str'>
print(type(len))           # <class 'builtin_function_or_method'>
print(type(object))        # <class 'type'>

🧠 Even types and classes are themselves objects in Python. Python follows a consistent object model, with everything derived from object.


🧱 Internal Structure of Python Objects

Each Python object has a fixed internal layout. At a high level, this includes:

ComponentDescription
type (__class__)Points to the object’s class
refcountNumber of references (used by garbage collector)
__dict__A dictionary storing instance attributes
__slots__Optional memory-saving layout for fixed attrs

🔎 Using __dict__ to Inspect Attributes

class Person:
    def __init__(self, name):
        self.name = name
        self.age = 30

p = Person("Alice")
print(p.__dict__)

✅ Output:

{'name': 'Alice', 'age': 30}

💡 All instance attributes are stored in the __dict__ unless __slots__ is defined.


💼 Optimize with __slots__

class User:
    __slots__ = ('username', 'email')

    def __init__(self, username, email):
        self.username = username
        self.email = email

✅ Benefits:

  • Saves memory (no __dict__)
  • Slight speed improvement
  • Prevents creation of new attributes

⚠️ __slots__ is optional and used in performance-critical code.


🧠 Understanding __class__

Every object has a reference to its class via __class__:

x = 10
print(x.__class__)  # <class 'int'>

🔁 Method Resolution Order (MRO)

MRO defines how Python looks up methods in case of inheritance.

✅ Example:

class A: pass
class B(A): pass
class C(B): pass

print(C.__mro__)

✅ Output:

(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

💡 Python uses the C3 Linearization Algorithm for MRO.


🧬 Identity and Memory with id()

x = "hello"
print(id(x))  # Memory address of object

id() returns the unique identity of an object, used for object comparison.


🧠 Interning of Small Objects

Python caches small immutable objects for performance.

a = 100
b = 100
print(a is b)  # ✅ True – same object (cached)

a = 1000
b = 1000
print(a is b)  # ❌ Might be False – not interned

🧰 Built-in Tools to Inspect Objects

FunctionUse Case
type(obj)Get the object’s class
dir(obj)List all available attributes/methods
hasattr(obj, x)Check if object has an attribute
getattr(obj, x)Dynamically get an attribute value
setattr(obj, x, v)Dynamically set an attribute
isinstance(obj, T)Check if object is an instance of a class

🧰 Real-World Use Case – Dynamic Object Introspection

def dump_object(obj):
    print(f"Class: {obj.__class__.__name__}")
    print("Attributes:", obj.__dict__)
    print("Methods:", [m for m in dir(obj) if callable(getattr(obj, m)) and not m.startswith("__")])

class Product:
    def __init__(self, name):
        self.name = name
    def display(self):
        print("Product:", self.name)

p = Product("Laptop")
dump_object(p)

✅ Useful for debuggers, serializers, and frameworks.


📘 Best Practices

✅ Do This❌ Avoid This
Use __slots__ for performance-critical classesAdding too many dynamic attributes
Use __dict__ and __class__ only for debuggingRelying on them in production logic
Use isinstance() for safe type checkingComparing types directly with ==
Understand id() and is for object identityConfuse with == (value comparison)

📌 Summary – Recap & Next Steps

Python object internals give you deep insight into how objects store attributes, manage memory, and resolve methods.

🔍 Key Takeaways:

  • ✅ All Python values are objects with class, attributes, and identity
  • ✅ Instance variables live in __dict__
  • ✅ Use __slots__ to reduce memory for fixed-attribute classes
  • ✅ MRO controls how methods are resolved in inheritance
  • id(), __class__, and dir() reveal internal structure

⚙️ Real-World Relevance:
Essential for writing frameworks, building ORMs, debugging tools, and performance optimization.


❓ FAQ – Python Object Internals

❓ What is __dict__?

✅ A dictionary holding an object’s writable attributes.

❓ What is __slots__ used for?

✅ To restrict attribute creation and save memory by removing __dict__.

❓ What’s the difference between is and ==?

  • is: checks object identity
  • ==: checks value equality

❓ How can I find an object’s class?

✅ Use obj.__class__ or type(obj).

❓ What is the MRO?

✅ MRO (Method Resolution Order) is the order Python uses to search for methods in a class hierarchy.


Share Now :

Leave a Reply

Your email address will not be published. Required fields are marked *

Share

Python Object Internals

Or Copy Link

CONTENTS
Scroll to Top