Code Explanation:
1. Defining the Descriptor Class
class D:
A class named D is defined.
This class will act as a descriptor.
Descriptors control how attributes are accessed and assigned.
2. Defining the __get__ Method
def __get__(self, obj, owner):
return obj.__dict__.get("v", 0)
__get__ is called when the attribute is accessed (read).
Parameters:
obj → instance accessing the attribute (c)
owner → the class (C)
It looks inside the instance’s dictionary (obj.__dict__) for key "v".
If "v" exists, it returns its value.
If "v" does not exist, it returns default 0.
So:
c.x will return c.__dict__["v"] if present, otherwise 0.
3. Defining the __set__ Method
def __set__(self, obj, val):
obj.__dict__["v"] = val
__set__ is called when the attribute is assigned (written).
obj is the instance (c).
val is the value being assigned (5).
It stores the value inside the instance dictionary under the key "v".
So:
c.x = 5 becomes c.__dict__["v"] = 5.
4. Defining the Class that Uses the Descriptor
class C:
x = D()
Class C is defined.
x is assigned an instance of D.
This makes x a managed attribute controlled by the descriptor.
5. Creating an Object
c = C()
An instance c of class C is created.
Initially:
c.__dict__ = {}
6. Assigning to c.x
c.x = 5
What happens internally:
Python sees x is a descriptor.
So it calls:
D.__set__(descriptor, c, 5)
That stores:
c.__dict__["v"] = 5
Now:
c.__dict__ = {"v": 5}
7. Accessing c.x
print(c.x)
What happens internally:
Python calls:
D.__get__(descriptor, c, C)
That returns:
c.__dict__.get("v", 0) → 5
So print prints 5.
8. Final Output
5


0 Comments:
Post a Comment