Reputation: 3001
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
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
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