So, I am reading a bit about metaclasses in Python, and how type()
's three-argument alter-ego is used to dynamically create classes. However, the third argument is usually a dict
that initializes the to-be created class' __dict__
variable.
If I want to dynamically create classes based on a metaclass that uses __slots__
instead of __dict__
, how might I do this? Is type()
still used in some fashion along with overriding __new__()
?
As an FYI, I am aware of the proper uses for __slots__
, to save memory when creating large numbers of a class versus abusing it to enforce a form of type-safety.
Example of a normal (new-style) class that sets __metaclass__
and uses a __dict__
:
class Meta(type):
def __new__(cls, name, bases, dctn):
# Do something unique ...
return type.__new__(cls, name, bases, dctn)
class Foo(object):
__metaclass__ = Meta
def __init__(self):
pass
In the above, type.__new__()
is called and the fourth argument (which becomes the third when actually used) creates a __dict__
in Foo
. But if I wanted to modify Meta
to include __slots__
, then I have no dictionary to pass on to type()
's __new__()
function (as far as I know -- I haven't tested any of this yet, just pondering and trying to find some kind of a use-case scenario).
Edit: A quick, but untested guess, is to take a dict of the values to be put into the __slots__
variables and pass it to type.__new__()
. Then add an __init__()
to Meta
that populates the __slots__
variables from the dict. Although, I am not certain how that dict would reach __init__()
, because the declaration of __slots__
prevents __dict__
from being created unless __dict__
is defined in __slots__
...
__slots__ solution From Python documentation: __slots__ allows us to explicitly declare data members (like properties) and deny the creation of __dict__ and __weakref__ (unless explicitly declared in __slots__ or available in a parent.)
Python | Use of __slots__ slots provide a special mechanism to reduce the size of objects.It is a concept of memory optimisation on objects. As every object in Python contains a dynamic dictionary that allows adding attributes.
A metaclass is the class of a class. A class defines how an instance of the class (i.e. an object) behaves while a metaclass defines how a class behaves. A class is an instance of a metaclass.
Metaclasses give us the ability to write code that transforms, not just data, but other code, e.g. transforming a class at the time when it is instantiated. In the example above, our metaclass adds a new method automatically to new classes that we define to use our metaclass as their metaclass.
You can't create a type with a non-empty __slots__ attribute. What you can do is insert a __slots__ attribute into the new class's dict, like this:
class Meta(type):
def __new__(cls, name, bases, dctn):
dctn['__slots__'] = ( 'x', )
return type.__new__(cls, name, bases, dctn)
class Foo(object):
__metaclass__ = Meta
def __init__(self):
pass
Now Foo has slotted attributes:
foo = Foo()
foo.y = 1
throws
AttributeError: 'Foo' object has no attribute 'y'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With