RoQuOTriX
RoQuOTriX

Reputation: 3001

Prevent creating new attributes for class or module

I saw this question on SO Prevent creating new attributes outside init which shows how to prevent adding new attributes to objects of classes.

I wanted the same behaviour for the overall class or even the complete loaded module.

Example class:

class Klass:
     a = 0
     b = 1

Another module:

from Klass import Klass

Klass.c = 2 # this should raise an error

Is this possible?

Upvotes: 3

Views: 1373

Answers (2)

Philippe Dixon
Philippe Dixon

Reputation: 87

The answer with slots would be the Pythonic way to do it.

class Klass:
    __slots__ = ['a', 'b']

    def __init__(self, a=0, b=1):
        self.a = a
        self.b = b
>>> k = klass.Klass()
>>> k.a
0
>>> k.b
1
>>> k.c = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Klass' object has no attribute 'c'
>>>

Upvotes: -1

Patrick Haugh
Patrick Haugh

Reputation: 60944

If you're trying to prevent modifying the class itself, you can create a metaclass that defines the __setattr__ method for the class.

class FrozenMeta(type):
    def __new__(cls, name, bases, dct):
        inst = super().__new__(cls, name, bases, {"_FrozenMeta__frozen": False, **dct})
        inst.__frozen = True
        return inst
    def __setattr__(self, key, value):
        if self.__frozen and not hasattr(self, key):
            raise TypeError("I am frozen")
        super().__setattr__(key, value)

class A(metaclass=FrozenMeta):
    a = 1
    b = 2

A.a = 2
A.c = 1 # TypeError: I am frozen

Upvotes: 5

Related Questions