'Forbid to add attributes to user-defined class in Python

When you create a user-defined class, you can, by default, dinamically add attributes to it just like in the next example:

# User defined class
class Test:
    def __init__(self):
        self.first_att = 5

test = Test()
test.second_att = 11
print(test.__dict__)
{'first_att': 5, 'second_att': 11}

But built-in classes don't allow such a thing:

# Built-in class
str_example = 'Test string'

str_example.added_att = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'added_att'

How can I modify my class Test so it doesn't allow it also? Thanks in advance



Solution 1:[1]

You can define in your class the allowed attributes by adding __slots__.
In there put the names of the attributes you want. All other attributes won't be accepted.
For example try this:

# User defined class
class Test:
    __slots__ = ("fitst_att", "your_att_name")

    def __init__(self):
        self.first_att = 5

test = Test()
test.your_att_name = 11
print(test.__dict__)
# test.second_att = 11  ##this will rais an error

Solution 2:[2]

You can achieve that by overwriting the __setattr__ method. As a very simple example for your case

class Test:
    def __init__(self):
        self.first_att = 5

    def __setattr__(self, key, value):
        if key not in ("first_att",):  # allowed attributes
            raise AttributeError(f"Not allowed to set attribute {key}")
        super().__setattr__(key, value)

Note that you have to add an exception list here that holds the names of the attributes you want to be able to assign values to.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Y_Z
Solution 2 Chris