Python Reflection Tutorial

Introduction

Reflection in Python refers to the ability of a program to inspect, modify, and manipulate its own structure and behavior at runtime. It allows you to dynamically examine and modify objects, classes, functions, and modules. Reflection is used for tasks like debugging, testing, and implementing dynamic behavior in your programs.

Table of Contents

  1. What is Reflection?
  2. Inspecting Objects
  3. Getting and Setting Attributes
  4. Working with Functions and Methods
  5. Inspecting Classes
  6. Using the inspect Module
  7. Practical Examples
  8. Conclusion

1. What is Reflection?

Reflection is the ability of a program to examine and modify its own structure and behavior at runtime. It enables dynamic access to information about classes, objects, methods, and modules, allowing for more flexible and adaptable code.

2. Inspecting Objects

You can inspect objects in Python using built-in functions like type(), id(), dir(), and getattr().

Example

class MyClass:
    def __init__(self, value):
        self.value = value

obj = MyClass(10)

# Inspecting the type of an object
print(type(obj))  # Output: <class '__main__.MyClass'>

# Inspecting the ID of an object
print(id(obj))  # Output: An integer representing the object's memory address

# Listing attributes and methods of an object
print(dir(obj))  # Output: A list of attributes and methods

3. Getting and Setting Attributes

You can dynamically get and set attributes of objects using getattr(), setattr(), hasattr(), and delattr().

Example

class MyClass:
    def __init__(self, value):
        self.value = value

obj = MyClass(10)

# Getting an attribute
print(getattr(obj, 'value'))  # Output: 10

# Setting an attribute
setattr(obj, 'value', 20)
print(obj.value)  # Output: 20

# Checking if an attribute exists
print(hasattr(obj, 'value'))  # Output: True

# Deleting an attribute
delattr(obj, 'value')
print(hasattr(obj, 'value'))  # Output: False

4. Working with Functions and Methods

You can inspect and call functions and methods dynamically using reflection.

Example

class MyClass:
    def __init__(self, value):
        self.value = value

    def display(self):
        print(f'Value: {self.value}')

obj = MyClass(10)

# Getting a method
method = getattr(obj, 'display')

# Calling the method
method()  # Output: Value: 10

5. Inspecting Classes

You can inspect classes to get information about their attributes, methods, base classes, and more.

Example

class MyClass:
    def __init__(self, value):
        self.value = value

    def display(self):
        print(f'Value: {self.value}')

# Inspecting class attributes and methods
print(MyClass.__dict__)

6. Using the inspect Module

The inspect module provides several useful functions for obtaining information about live objects, including modules, classes, methods, functions, tracebacks, and frame objects.

Example

import inspect

class MyClass:
    def __init__(self, value):
        self.value = value

    def display(self):
        print(f'Value: {self.value}')

obj = MyClass(10)

# Getting the class of an object
print(inspect.getmembers(obj, inspect.isclass))

# Getting the methods of an object
print(inspect.getmembers(obj, inspect.ismethod))

# Getting the source code of a function
print(inspect.getsource(MyClass.display))

7. Practical Examples

Example 1: Dynamic Function Invocation

def greet(name):
    return f'Hello, {name}!'

def farewell(name):
    return f'Goodbye, {name}!'

# Function mapping
functions = {
    'greet': greet,
    'farewell': farewell
}

# Dynamically calling functions
name = 'Alice'
print(functions['greet'](name))     # Output: Hello, Alice!
print(functions['farewell'](name))  # Output: Goodbye, Alice!

Example 2: Dynamic Class Instantiation

class Dog:
    def speak(self):
        return "Woof!"

class Cat:
    def speak(self):
        return "Meow!"

# Class mapping
classes = {
    'dog': Dog,
    'cat': Cat
}

# Dynamically creating instances
animal_type = 'dog'
animal = classes[animal_type]()
print(animal.speak())  # Output: Woof!

8. Conclusion

Reflection in Python provides powerful tools for inspecting and manipulating objects, classes, functions, and modules at runtime. By understanding and utilizing reflection, you can write more flexible, adaptable, and dynamic code. This tutorial covered the basics of reflection, including inspecting objects, getting and setting attributes, working with functions and methods, inspecting classes, using the inspect module, and practical examples.

Comments