http://www.voidspace.org.uk/python/articles/five-minutes.shtml
Metaclasses in Five Minutes
Originally a lightning talk first given at PyCon UK 2008.
Metaclasses have a reputation for being 'deep-black-magic' in Python. The cases where you need them are genuinely rare (unless you program with Zope...), but the basic principles are surprisingly easy to understand.
Typically the term type is used for the built-in types and the term class for user-defined classes. Since Python 2.2 there has been no real difference and 'class' and 'type' are synonyms.
For classic (old-style) classes, their type is types.ClassType.
Here we can see that a class created at the interactive interpreter is a first class object.
Its metaclass...
Just as an object is an instance of its class; a class is an instance of its metaclass.
The metaclass is called to create the class.
In exactly the same way as any other object in Python.
The interpreter calls the metaclass to create it...
For a normal class that inherits from object this means that type is called to create the class:
>>> help(type) Help on class type in module __builtin__: class type(object) | type(object) -> the object's type | type(name, bases, dict) -> a new type
It is this second usage of type that is important. When the Python interpreter executes a class statement (like in the example with the interactive interpreter from a couple of sections back), it calls type with the following arguments:
This code creates a dictionary of class attributes, and then calls type to create a class called Hello.
We can provide a custom metaclass by setting __metaclass__ in a class definition to any callable that takes the same arguments as type.
The normal way to do this is to inherit from type:
The important thing is that inside the body of the __new__ method we have access to the arguments passed to create the new class. We can introspect the dictionary of attributes and modify, add or remove members.
It is important to override __new__ rather than __init__. When you instantiate a class both __init__ and __new__ are called. __init__ initialises an instance - but __new__ is responsible for creating it. So if our metaclass is going to customise class creation we need to override __new__ on type.
The reason to use a new type rather than just a factory function is that if you use a factory function (that just calls type) then the metaclass won't be inherited.
WhizzBang is a class, but instead of being an instance of type the class object is now an instance of our custom metaclass...
Well (I'm glad you asked)... our metaclass will be called whenever a new class is created that uses it. Here are some ideas:
The important things is that the class is only actually created by the final call to type in the metaclass - so you are free to modify the dictionary of attributes as you see fit (and the name plus the tuple of base classes of course).
Several of the popular Python ORM (Object Relational Mappers for working with databases) use metaclasses in these ways.
Oh, and because metaclasses are inherited so you can provide a base-class that uses your metaclass and sub-classes inherit it without explicitly having to declare it.
I've ever needed to use one in production code... (I have used them for profiling and we make extensive use of them in Ironclad - but I didn't write these.)
Of course all this only applies to Python 2.X. The mechanism changes in Python 3.
type(type) is type
With Python 2.6 you can now use class decorators to achieve a lot of the things that previously you might have used metaclasses for.
For a truly awful example (with a slightly more in depth but still easy-to-digest look at metaclasses) see The Selfless Metaclass. It does bytecode and method signature rewriting to avoid the need to explicitly declare self.
[1] | A 'one-pl' is tuple with only one element... |