Now let's create a function that will decorate a class with a method that issues alerts whenever the 'mileage' attribute is read.
Look at the code in the editor. Let's analyze it:
- line 1:
def object_counter(class_):
– this line defines a decorating function that accepts one parameter 'class_' (note the underscore) - line 2:
class_.__getattr__orig = class_.__getattribute__
– the decorator makes a copy of the reference to the__getattribute__
special method. This method is responsible for returning the attribute values. The reference to this original method will be used in a modified method; - line 4:
def new_getattr(self, name):
– a definition of the method playing the role of the new__getattribute__
method starts here. This method accepts an attribute name – it’s a string; - line 5:
if name == 'mileage':
– in case some code asks for the 'mileage' attribute, the next line will be executed; - line 6:
print('We noticed that the mileage attribute was read')
– a simple alert is issued; - line 7:
return class_.__getattr__orig(self, name)
– the original method__getattribute__
referenced byclass.__getattr__orig
is called. This ends the 'new_getattr' function definition; - line 9:
class_.__getattribute__ = new_getattr
– now the 'new_getattr' is defined, so it can now be referenced as the new '__getattribute__' method by a decorated class; - line 10:
return class_
– every well behaved and developed decorator should return the decorated object – in our case it is a decorated class.
The last thing we should do is decorate the Car class:
@object_counter
class Car:
When you run the code, you can see that access to the 'mileage' attribute has been detected:
We noticed that the mileage attribute was read
The mileage is 0
The VIN is ABC123
output
Code
def object_counter(class_):class_.__getattr__orig = class_.__getattribute__
def new_getattr(self, name):
if name == 'mileage':
print('We noticed that the mileage attribute was read')
return class_.__getattr__orig(self, name)
class_.__getattribute__ = new_getattr
return class_
{{ dockerServerErrorMsg }}
×
{{ errorMsg }}
×
{{ successMsg }}
×