Python Attribute Logging Metaclass: Monitor Accesses
Python Metaprogramming: Exercise-4 with Solution
Attribute Logging Metaclass:
Write a Python metaclass “AttrLoggingMeta” that logs every time an attribute is accessed or modified.
Sample Solution:
Python Code :
# Define a metaclass AttrLoggingMeta
class AttrLoggingMeta(type):
# Override the __new__ method to log attribute accesses
def __new__(cls, name, bases, dct):
# Iterate through class attributes
for key, value in dct.items():
# Exclude special methods
if not key.startswith('__'):
# Replace attribute with a logged version
dct[key] = cls.log_access(key, value)
# Call superclass's __new__ method to create the class
return super().__new__(cls, name, bases, dct)
# Define a static method to log attribute accesses
@staticmethod
def log_access(name, value):
# If the attribute is a method, wrap it to log method calls
if callable(value):
def wrapper(*args, **kwargs):
print(f"Calling method {name}")
return value(*args, **kwargs)
return wrapper
else:
# If the attribute is a property, log read and write operations
return property(
# Log attribute read operation
fget=lambda self: AttrLoggingMeta.log_read(name, value, self),
# Log attribute write operation
fset=lambda self, v: AttrLoggingMeta.log_write(name, v, self)
)
# Define a static method to log attribute reads
@staticmethod
def log_read(name, value, instance):
print(f"Reading attribute {name}")
return value
# Define a static method to log attribute writes
@staticmethod
def log_write(name, value, instance):
print(f"Writing attribute {name} with value {value}")
# Update instance dictionary with the new value
instance.__dict__[name] = value
# Define a class LoggedClass using AttrLoggingMeta as its metaclass
class LoggedClass(metaclass=AttrLoggingMeta):
# Define a class attribute foo
foo = 42
# Define a class method bar
def bar(self):
return 'baz'
# Create an instance of LoggedClass
instance = LoggedClass()
# Access and print the value of the foo attribute
print(instance.foo) # Reading attribute foo
# Set the value of the foo attribute
instance.foo = 78 # Writing attribute foo with value 84
# Call the bar method
instance.bar() # Calling method bar
Output:
Reading attribute foo 42 Writing attribute foo with value 78 Calling method bar
Explanation:
- Metaclass AttrLoggingMeta:
- This metaclass is responsible for logging attribute accesses of classes that use it.
- The "new" method is overridden to intercept attribute assignments and replace them with logged versions.
- Inside "new", it iterates over the class attributes (excluding special methods) and replaces them with logged versions using the 'log_access' method.
- Static Method log_access:
- This method is called to replace each attribute with a logged version.
- If the attribute is a method, it wraps it with a wrapper function that logs method calls.
- If the attribute is a property, it replaces it with a property that logs read and write operations.
- Static Methods log_read and log_write:
- These methods are called to log read and write operations of properties.
- They print messages indicating the attribute name and the operation being performed.
- Class LoggedClass:
- This class is an example demonstrating the use of the "AttrLoggingMeta" metaclass.
- It contains a class attribute 'foo' and a method 'bar'.
- Instance Creation and Testing:
- An instance of 'LoggedClass' is created.
- The value of the 'foo' attribute is accessed, demonstrating logging of attribute reads.
- The value of the 'foo' attribute is changed, demonstrating logging of attribute writes.
- The "bar" method is called, demonstrating logging of method calls.
Python Code Editor :
Have another way to solve this solution? Contribute your code (and comments) through Disqus.
Previous: Python Singleton Metaclass: Ensure One Instance.
Next: Python Dynamic Class Creation: Flexibility Unleashed
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.
It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.
https://198.211.115.131/python-exercises/metaprogramming/python-metaprogramming-exercise-4.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics