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.