1
class Test():
    def __init__(self,age):
        self.age=age
    def __getattribute__(self,attribute):
        print("Initializing getattribute")
        return 6
    def __setattr__(self,attribute,value):
        print("Initializing setattr")
        return object.__setattr__(self,attribute,value)
test=Test(4)
test.age
print(test.age)

From the code above the result is :

Initializing setattr
Initializing getattribute
Initializing getattribute
6

I understand where each dunder method is called, but what do they really do?In the previous example getattribute dictate the attribute value and if I delete the line :

return object.__setattr__(self,attribute,value)

Nothing changes.

So what does __setattr__ do?

  • Does this answer your question? [Python metaclasses: Why isn't \_\_setattr\_\_ called for attributes set during class definition?](https://stackoverflow.com/questions/10762088/python-metaclasses-why-isnt-setattr-called-for-attributes-set-during-class) – aymenim Feb 04 '21 at 15:21

1 Answers1

0

__getattribute__ is called before any other attempt is made to access an attribute. No matter what __setattr__ does, test.age is handled by test.__getattribute__("age"), which returns 6 whether or not there is an attribute named age.

If you get rid of __getattribute__:

class Test():
    def __init__(self,age):
        self.age=age
    def __setattr__(self,attribute,value):
        print("Initializing setattr")
        return object.__setattr__(self,attribute,value)

test=Test(4)
test.age
print(test.age)

The class behaves normally, setting test.age to 4. If you further get rid of the call to object.__setattr__, then you'll get an AttributeError because self.age = age will never actually create or set the age attribute; it just prints the initialization message and returns:

class Test():
    def __init__(self,age):
        self.age=age
    def __setattr__(self,attribute,value):
        print("Initializing setattr")

test=Test(4)
test.age
print(test.age)

results in

Initializing setattr
Traceback (most recent call last):
  File "/Users/chepner/tmp.py", line 11, in <module>
    test.age
AttributeError: 'Test' object has no attribute 'age'
chepner
  • 497,756
  • 71
  • 530
  • 681