π Python Reflection β Use getattr
, setattr
, dir
and More
π§² Introduction β Why Use Reflection in Python?
In dynamic languages like Python, reflection allows you to examine, modify, and invoke objects and their attributes at runtimeβwithout knowing their names at coding time.
Reflection is powerful when you want to:
- Dynamically access attributes and methods
- Build flexible frameworks, serializers, or ORMs
- Write generic and reusable code
π― In this guide, youβll learn:
- What reflection is in Python
- How to use functions like
getattr
,setattr
,hasattr
,type
,dir
- Real-world examples (e.g., API clients, data validation)
- Best practices and pitfalls
β What Is Reflection in Python?
Reflection is the ability of a program to inspect and manipulate its own structure (variables, methods, classes) at runtime.
Python supports reflection using built-in functions and introspection tools.
π Key Reflection Functions in Python
Function | Purpose |
---|---|
getattr() | Get the value of an attribute |
setattr() | Set the value of an attribute |
hasattr() | Check if an object has an attribute |
delattr() | Delete an attribute |
type() | Get the type of an object |
isinstance() | Check class inheritance |
callable() | Check if an object is callable |
dir() | List all attributes and methods of an object |
π§ͺ Example β Using getattr
, setattr
, hasattr
class Person:
def __init__(self):
self.name = "Alice"
def greet(self):
return f"Hello, {self.name}"
p = Person()
# Reflection in action
print(getattr(p, 'name')) # Alice
print(hasattr(p, 'greet')) # True
setattr(p, 'name', 'Bob')
print(p.greet()) # Hello, Bob
π§± Use Case β Dynamic Method Calling
class Calculator:
def add(self, a, b): return a + b
def subtract(self, a, b): return a - b
calc = Calculator()
method_name = 'add'
if hasattr(calc, method_name):
func = getattr(calc, method_name)
print(func(5, 3)) # 8
β Dynamically calling a method using its name as a string.
π§ Inspecting Class Metadata with type
and dir
class Example:
def __init__(self):
self.x = 10
def method(self): pass
e = Example()
print(type(e)) # <class '__main__.Example'>
print(dir(e)) # Lists all attributes and methods
𧬠Real-World Application β 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 = "Pen"
self.price = 10
p = Product()
print(serialize(p)) # {'name': 'Pen', 'price': 10}
β Use reflection to build a generic serializer.
π§ Reflection vs Introspection
Feature | Reflection | Introspection |
---|---|---|
Purpose | Inspect and modify runtime behavior | Inspect only (non-modifying) |
Tools | getattr() , setattr() | type() , dir() , isinstance() |
Example Use | Dynamic method calls, attribute setting | Type checking, debugging |
π Best Practices
β Do This | β Avoid This |
---|---|
Use reflection for framework design | Overusing it for basic tasks |
Always check with hasattr() before getattr() | Risk of AttributeError otherwise |
Avoid using reflection when unnecessary | Can hurt readability and performance |
Combine with decorators for dynamic behavior | Using in performance-critical loops |
π Summary β Recap & Next Steps
Reflection in Python enables you to dynamically explore and interact with objects at runtime, making it ideal for frameworks, APIs, testing, and dynamic execution.
π Key Takeaways:
- β
Use
getattr
,setattr
,hasattr
, anddir()
to interact with objects - β Reflection is powerful but should be used judiciously
- β Helps with dynamic dispatch, serialization, and generic programming
- β οΈ May reduce performance and clarity if overused
βοΈ Real-World Relevance:
Reflection powers ORMs (like SQLAlchemy), testing frameworks (like pytest), and dynamic APIs.
β FAQ β Python Reflection
β What is reflection in Python?
β Reflection lets you inspect and modify objects, classes, and methods at runtime.
β How do I get the value of an attribute by name?
β
Use getattr(obj, 'attr_name')
.
β How do I check if a method exists before calling it?
β Use:
if hasattr(obj, 'method_name'):
getattr(obj, 'method_name')()
β Can reflection hurt performance?
β Yes, especially if used in tight loops or frequently accessed logic.
β Is Pythonβs reflection the same as Javaβs?
πΈ Similar in concept, but Python uses dynamic typing and simpler tools (getattr
, dir
) instead of Javaβs Reflection API
.
Share Now :