I created this class to test some of the __getattr__
features:
class Trace:
def __init__(self, val):
self.val = val
def __setattr__(self, attr, value):
print('set ' + attr)
def __getattr__(self, attr):
print('get ' + attr)
I then created an instance
a = Trace(10)
print(a.val)
a.val = 5
print(a.val)
But, even if I fetched only existing attributes, this was the output:
set val
get val
None
set val
get val
None
I'm using Python 3.7.
__getattr__
is only called when an attribute isn’t found normally, but __setattr__
has no such restriction (that’s why there’s no equivalent of __getattribute__
for it). You overrode __setattr__
to not actually set an instance attribute, so the attribute is always missing and __getattr__
is called anyway. (Yes, it applies in __init__
too.)
Remove __setattr__
to see your expected behaviour quickly, or add its default behaviour back:
def __setattr__(self, attr, value):
print('set ' + attr)
super().__setattr__(attr, value)