Code Explanation:
๐น 1. Class Definition
class Test:
You are defining a class named Test.
๐น 2. Overriding __getattribute__
def __getattribute__(self, name):
This method is called for every attribute access on an object.
It runs before anything else, even before __getattr__.
➤ Inside __getattribute__
if name == "x":
return 100
If someone tries to access obj.x, this condition becomes true.
It directly returns 100.
No further lookup happens.
return super().__getattribute__(name)
For any other attribute:
It calls the default attribute lookup mechanism using super().
If the attribute exists → returns it.
If it does NOT exist → raises AttributeError.
๐น 3. Overriding __getattr__
def __getattr__(self, name):
This method is called only when the attribute is NOT found normally.
It acts as a fallback handler.
➤ Inside __getattr__
return 200
If an attribute doesn’t exist (like y), this method returns 200.
๐น 4. Object Creation
obj = Test()
Creates an instance of the Test class.
๐น 5. Printing Values
print(obj.x, obj.y)
Let’s break this step carefully:
➤ Accessing obj.x
__getattribute__ is called with name = "x".
Condition name == "x" is True.
Returns 100.
✔️ So, obj.x = 100
➤ Accessing obj.y
__getattribute__ is called with name = "y".
Condition fails → goes to:
super().__getattribute__("y")
Python tries to find y → it does NOT exist → raises AttributeError.
Since error occurred → Python calls __getattr__.
__getattr__ returns 200.
✔️ So, obj.y = 200
๐น 6. Final Output
100 200

0 Comments:
Post a Comment