You were on the right track, I think it’s more of a syntax error problem than something else, take 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)
Basically it’s the same code you wrote, with the difference that the method __setattr__
is written as a method correctly.
When executing this code, a AttributeError:
:
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 attribute c
was not created in the object, it was ignored.
However, there is a side effect when overriding the method __setattr__
with this behavior, no attribute is accepted by the class, that is, not even those declared in the method __init__
(a
and b
).
A possible solution would be to declare a list of permissible attributes and base on that list, rather than 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)
Before I used a condition variable and performed a function that required the
__setattr__
to read if the variable was true and then locked the object to new attributes... using the slots really got less "feature-technical" rs– LeandroLuk
a problem I have identified in relation to
__slots__
is that if I have "nested classes" defined within the class where they serve to complement a list, the element slots conflicts with the parent class– LeandroLuk