How to create an object of a class without __dict__

class B(type):
    __slots__ = ()

class A(metaclass=B):
    pass

A.test = "test"

      

"A"

is an instance of a metaclass "B"

and "B"

has a __slots__

specific - why do I have it __dict__

in the class A

? How can I create a class object without __dict__

?

+3


source to share


2 answers


You cannot do this; classes always have __dict__

.

You can only use __slots__

for classes to instantiate without __dict__

, not for meta types. Usually you only create a few classes, so there is no support in metaclasses __slots__

.



Do not use __slots__

to prevent setting attributes. Use instead __setattr__

:

class NoAttributesClassMeta(type):
    def __setattr__(cls, name, value):
        if name not in cls.__dict__:
            raise AttributeError("Cannot set attributes")
        type.__setattr__(cls, name, value)

      

+3


source


__slots__

will not stop you from setting an attribute for a class, for that you need to override __setattr__

. Something like this should do it:

class B(type):
    def __new__(cls, clsname, bases, dct):
        dct['__slots__']  = ('x',)
        return type.__new__(cls, clsname, bases, dct)
    def __setattr__(cls, attr, val):
        if attr not in cls.__slots__:
            raise AttributeError('Can\'t set {!r}'.format(attr))
        else:
            type.__setattr__(cls, attr, val)

class A(metaclass=B):
    pass

      



Demo:

>>> A.x = 1
>>> A.y = 2
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    A.y = 2
  File "C:\Python27\so.py", line 7, in __setattr__
    raise AttributeError('Can\'t set {!r}'.format(attr))
AttributeError: Can't set 'y'

      

+2


source







All Articles