🧠 Python Introspection & Useful Dunder Methods Guide
Beginner-friendly documentation about useful Python dunder attributes and introspection tools commonly used for debugging, classes, logging, and development workflows.
This document explains:
- __name__
- __class__
- __dict__
- __module__
- type()
- getting class names
- getting function names
- debugging patterns
- introspection basics
📚 Table of Contents
- 📖 What is Introspection?
- 🏷️ name
- 🏛️ class
- 📦 dict
- 📁 module
- 🔍 type()
- 🎯 Getting Class Names
- ⚙️ Getting Function Names
- 🛠️ Useful Debugging Patterns
- 🎮 Real 42 Examples
- ⚠️ Common Beginner Mistakes
- 📚 Best Practices
- 📚 Final Notes
📖 What is Introspection?
Introspection means: - inspecting Python objects dynamically
Python allows you to inspect: - classes - objects - functions - modules - attributes
Very useful for: - debugging - logging - parsers - large projects
🏷️ name
__name__ stores:
- the name of a function
- the name of a module
Function Example
def move():
pass
print(move.__name__)
Output:
move
Module Example
print(__name__)
Usually outputs:
__main__
when running the file directly.
🏛️ class
__class__ gives:
- the object's class
Example
class Drone:
pass
drone = Drone()
print(drone.__class__)
Output:
<class '__main__.Drone'>
📦 dict
__dict__ stores:
- object attributes
Example
class Player:
def __init__(self):
self.hp = 100
self.name = "Sara"
player = Player()
print(player.__dict__)
Output
{'hp': 100, 'name': 'Sara'}
Why dict is Useful
Useful for: - debugging - serialization - quick inspection
📁 module
__module__ shows:
- where the class/function was defined
Example
print(Player.__module__)
🔍 type()
type() returns:
- the object's type
Example
print(type(player))
Output:
<class '__main__.Player'>
🎯 Getting Class Names
Very common debugging pattern.
Example
print(player.__class__.__name__)
Output:
Player
Why This is Useful
Useful for: - debugging - logging - error reporting - game systems
⚙️ Getting Function Names
Functions also store their names.
Example
def validate():
pass
print(validate.__name__)
Output:
validate
Using Inside Debugging
print(f"Failed inside function: {validate.__name__}")
🛠️ Useful Debugging Patterns
Printing Class Names
print(type(obj).__name__)
Example Output
Maze
Printing Function Names
print(function.__name__)
Printing Object Attributes
print(obj.__dict__)
Printing Exception Types
print(type(e).__name__)
🎮 Real 42 Examples
Parser Debugging
print(type(zone).__name__)
Maze Debugging
print(maze.__dict__)
Function Tracking
print(generate_maze.__name__)
Error Reporting
print(f"{type(e).__name__}: {e}")
⚠️ Common Beginner Mistakes
❌ Confusing name Types
Functions:
- have __name__
Objects: - usually do not
❌ Printing Entire Objects Accidentally
print(obj)
may not be useful without:
- __str__
❌ Modifying dict Incorrectly
Changing __dict__ directly may:
- create bugs
- break objects
📚 Best Practices
- Use introspection mainly for debugging
- Keep debug prints readable
- Use meaningful class names
- Avoid excessive debug output
- Prefer structured logging in large projects
🧠 Why Introspection Matters
Introspection helps: - understand objects dynamically - debug faster - inspect large systems - improve logging
Very useful in: - parsers - frameworks - MLX projects - game systems - debugging tools
📚 Final Notes
Python introspection is one of the language's most powerful features.
Understanding these tools helps: - debug efficiently - inspect objects dynamically - improve architecture - build better development workflows
These patterns become increasingly useful in larger Python projects.