π Python Reflection β Dynamic Access with getattr, dir, setattr
π§² Introduction β Why Use Reflection?
Reflection is a powerful feature in Python that allows a program to examine and manipulate its own structure and behavior at runtime. This means:
- You can access or change attributes/methods dynamically
- You can build generic, flexible, and plugin-friendly code
- You donβt need to know the names of classes or methods ahead of time
π― In this guide, you’ll learn:
- What reflection is and how it works in Python
- How to use getattr(),setattr(),hasattr(),dir(), and more
- Real-world examples: dynamic APIs, serializers, testing
- Best practices and common pitfalls
β What Is Reflection in Python?
Reflection in Python refers to the ability to inspect and manipulate classes, objects, methods, and modules dynamically at runtime.
π οΈ Core Reflection Tools
| Function | Purpose | 
|---|---|
| type(obj) | Returns the type of an object | 
| id(obj) | Returns the unique ID (memory address) | 
| dir(obj) | Lists all attributes/methods of an object | 
| getattr() | Gets the value of an attribute dynamically | 
| setattr() | Sets an attribute value dynamically | 
| hasattr() | Checks if an object has an attribute | 
| delattr() | Deletes an attribute from an object | 
| callable() | Checks if an object is callable (e.g. function) | 
π§ͺ Example β Reflecting on an Object
class Person:
    def __init__(self):
        self.name = "Alice"
    def greet(self):
        return f"Hello, {self.name}"
p = Person()
# Reflection in action
print(type(p))              # <class '__main__.Person'>
print(dir(p))               # Lists attributes like 'name', 'greet', '__init__', etc.
print(getattr(p, "name"))   # Alice
setattr(p, "name", "Bob")
print(p.greet())            # Hello, Bob
π§± Dynamic Method Invocation
class Math:
    def add(self, a, b):
        return a + b
m = Math()
method_name = "add"
if hasattr(m, method_name):
    func = getattr(m, method_name)
    print(func(5, 3))  # Output: 8
π‘ You donβt need to hardcode method names. Perfect for plugin systems or command routers.
π Using dir() and type() for Introspection
class Demo:
    def __init__(self):
        self.value = 42
d = Demo()
print(dir(d))      # Shows all attributes/methods
print(type(d))     # <class '__main__.Demo'>
print(callable(d)) # False
π§° Real-World Use Case β Object Serializer
def serialize(obj):
    return {
        key: getattr(obj, key)
        for key in dir(obj)
        if not key.startswith("_") and not callable(getattr(obj, key))
    }
class Product:
    def __init__(self):
        self.name = "Phone"
        self.price = 500
p = Product()
print(serialize(p))  # {'name': 'Phone', 'price': 500}
π‘ Reflection helps build generic, reusable utilities.
π§ Reflection vs Introspection
| Concept | Reflection | Introspection | 
|---|---|---|
| Definition | Inspect and modify object structure | Only inspect object structure | 
| Example Tools | getattr(),setattr() | type(),isinstance(),dir() | 
| Use Case | Dynamic invocation, plugin design | Type checking, object inspection | 
β οΈ Common Pitfalls
| β Mistake | β Fix | 
|---|---|
| Not checking hasattr() | Use hasattr(obj, "attr")beforegetattr() | 
| Overusing reflection in simple cases | Use direct access when possible | 
| Relying on reflection for safety-critical logic | Avoid in security-sensitive contexts | 
π Best Practices
| β Recommended | β Avoid This | 
|---|---|
| Use hasattr()beforegetattr() | Blind access without checks | 
| Use reflection in dynamic systems | Using it for basic static behavior | 
| Document dynamic behavior clearly | Making reflection-based code opaque | 
| Combine with decorators | Skipping validation and control | 
π Summary β Recap & Next Steps
Reflection in Python allows you to dynamically inspect and interact with code. Itβs ideal for writing flexible, generic, and reusable software components.
π Key Takeaways:
- β
 Use getattr(),setattr(),hasattr(),dir()to work with object attributes
- β Great for plugin systems, serializers, APIs, test runners
- β Avoid unnecessary complexityβuse reflection when truly needed
βοΈ Real-World Relevance:
Reflection powers ORMs (like SQLAlchemy), framework internals (like Django), and test runners (like pytest).
β FAQ β Python Reflection
β What is reflection in Python?
β Itβs the ability to examine and modify objects, classes, and functions at runtime.
β How do I get the value of an attribute by name?
β
 Use getattr(obj, 'attribute_name').
β Can I check if a method exists?
β Yes. Use:
if hasattr(obj, 'method_name'):
    getattr(obj, 'method_name')()
β What is the difference between reflection and introspection?
- Reflection allows inspection + modification
- Introspection allows only inspection
β Is reflection bad practice?
β Not inherently. But overusing reflection can make your code harder to debug and slower in performance-critical areas.
Share Now :
