You were on the right track, I think it's more of a syntax error problem than something else, see this example:
class Foo:
def __init__(self, a, b):
self.a = a
self.b = b
def __setattr__(self, key, value):
if not hasattr(self, key):
return
super().__setattr__(key, value)
if __name__ == '__main__':
f = Foo('a', 'b')
f.c = 'c'
print(f.c)
It's basically the same code you wrote, with the difference that the __setattr__
method is written as a method correctly.
When executing this code, a AttributeError:
happens:
Traceback (most recent call last):
File "attr.py", line 15, in <module>
print(f.c)
AttributeError: 'Foo' object has no attribute 'c'
That is, the c
attribute was not created on the object, it was ignored.
However, there is a side effect, by overriding the __setattr__
method with this behavior, no attribute is accepted by the class, ie not even declared in method __init__
( a
and b
).
A possible solution would be to declare a list of allowed attributes and to base it on that list, instead of checking the attributes that the object has:
class Foo:
attributes = ('a', 'b')
def __init__(self, a, b):
self.a = a
self.b = b
def __setattr__(self, key, value):
if key not in self.attributes:
return
super().__setattr__(key, value)