Code Explanation:
1. Defining the descriptor class
class Scale:
This defines a class named Scale.
Objects of this class act as descriptors that control attribute access.
2. Implementing __get__
def __get__(self, obj, owner):
return obj.__dict__.get("_x", 1) * 10
__get__ makes Scale a descriptor.
Parameters:
self → the descriptor object (Scale()).
obj → the instance accessing the attribute (i).
owner → the class (Item).
obj.__dict__.get("_x", 1):
Tries to read _x from the instance.
If _x does not exist, it uses default value 1.
The value is then multiplied by 10.
So this descriptor returns a computed value, not a stored one.
3. Defining the owner class
class Item:
This defines a class named Item.
4. Attaching the descriptor
x = Scale()
x is a class attribute.
It is managed by the Scale descriptor.
Accessing x will trigger Scale.__get__.
5. Creating an instance
i = Item()
An object i of class Item is created.
6. Setting the backing attribute
i._x = 3
_x is a normal instance attribute.
It acts as a backing field used internally by the descriptor.
The descriptor does not store values itself.
7. Accessing the descriptor-managed attribute
print(i.x)
๐ What happens when i.x is accessed:
Python finds x in the class Item.
x is a descriptor, so Scale.__get__ is called.
obj.__dict__.get("_x", 1) returns 3.
3 * 10 is calculated.
The final value returned is 30.
✅ Final Output
30

0 Comments:
Post a Comment