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__…
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:
Now Foo has slotted attributes:
throws