Snake_Byte #13: Metaclasses: But Why?

Python is one of a handful of languages that allow the use of Metaclasses. Usage of the feature is fairly controversial, as you can solve some of the same problems with other patterns, but using them can provide plenty of mystery and magic to defining classes, allowing you to amuse yourself by watching your coworkers as they try to visualize the instance creation model in their minds. I won’t be covering in detail what a metaclass is, other than to say it’s a class whose instances are classes. Ionel Cristian Mărieș has provided an in depth post, on the subject, that I would recommend, if you’re interested in all of the various ways to create horrible things with this feature.
So, why would you ever want to use a Metaclass? There are many bad reasons, but one sinister thing I’ve found fun is using them to gain control of instance initialization when extending classes from third party libraries, or classes where I have less control of the data structure definition of properties. That way people can be mystified as to how their classes end up with the properties that they do by simply extending my class.
Let’s start with a simple class that has 2 properties, a list and a dict. How can I impose these defaults, that I provide, on folks who unwittingly extend my class? If my properties were strings, then obliterating my sensible initialization values makes sense, but since they are data structures themselves, perhaps children classes just want to modify a piece of the default values instead of the whole thing. A safe assumption.

As you can see, everything works as expected. The parent properties are fully overridden. Now, let’s allow the parent data structures to come along on the initialization ride with a Metaclass.

Here we’ve created a metaclass that grabs the list and dict properties that we care about from the immediate parent and combines or extends them with the properties set on the child class. All we have to do now is to tell our parent class to use this metaclass.

Now that it’s all hooked up, let’s see the full example:

As you can see, now the properties have been combined with the parents defaults, which is what everyone wanted right? Great fun.
Python’s class system is very flexible, and excellent, in my opinion despite the serious tone of this snippet. Leveraging these powerful features can lead to great things, but measure twice and cut once.