Investigating Classes with Introspection and Reflection
The beauty of reflection and introspection lies in their universality – they can be applied to any object, regardless of its origin. Let's delve into a practical example to solidify this understanding:
class MyClass:
pass
obj = MyClass()
obj.a = 1
obj.b = 10
obj.c = 100
obj.int = 11
obj.img = 22
obj.ix = 33
def increment_int_attributes_starting_with_i(obj):
for name in obj.__dict__.keys():
if name.startswith('i'):
val = getattr(obj, name)
if isinstance(val, int):
setattr(obj, name, val + 1)
print(obj.__dict__)
increment_int_attributes_starting_with_i(obj)
print(obj.__dict__)
Output:
Step by Step Explanation:
- Creating the Object: We begin by defining a simple class
MyClass. We then create an instance of this class named obj.
- Assigning Attributes: The object
obj is populated with various attributes, each with different values. These attributes include a, b, c, int, img, and ix.
- Defining the Manipulation Function: The function
increment_int_attributes_starting_with_i is designed to inspect the object's attributes. It identifies attributes whose names start with 'i', checks if their values are integers, and increments them if they meet these criteria.
- Displaying Initial Attributes: Before applying the manipulation function, we print the initial attributes of the object. This provides a baseline to observe changes.
- Applying the Manipulation: The manipulation function is called, and it processes the object's attributes. In this example, attributes with names starting with '
i' (such as int, img, and ix) are integers, so they are incremented.
- Displaying Manipulated Attributes: After the manipulation, we print the object's attributes again to observe the changes made by the function.
By using a descriptive function name like increment_int_attributes_starting_with_i, you make it clearer what the function does without needing to examine its implementation in detail. This practice improves the readability and maintainability of your code.