An operational explanation of Python metaclasses (part 2)
After modifying a class as it's being created (covered in part 1), the next thing you can do with a metaclass is
get a chance to do things when instances of the class are created.
You do this by defining
__call__ on your metaclass:
class MiniMeta(type): def __call__(cls, *args, **kwargs): return super(MiniMeta, cls).\ __call__(*args, **kwargs) class Example(object): __metaclass__ = MiniMeta
There are a number of things that you can do with this. One of them
(which I first saw in another metaclass tutorial) is handling deferred
initialization and setup of something related to the class. Rather than
doing this in your metaclass
__init__, you defer it
until the first time an instance of the class is created; this saves
you effort in situations where many classes are defined but only a few
classes will ever be used to create instances.
Using a metaclass
__call__ to customize instance creation runs into
the obvious question of why you don't just do the same work in the
__init__ method (or in extreme cases, its
method). Probably the right answer is if you have a chunk of common
behavior across a bunch of classes and the classes can't easily be put
into an inheritance relationship where this functionality can be pulled
into a common ancestor or mixin class.
(This use of metaclasses is considered sufficiently interested to
get mentioned in passing in the official documentation for
__call__ is actually a specific example of a general metaclass
power. I'll get to the general power later because it requires more
Sidebar: a technicality
Strictly speaking using
__call__ does not intercept all instance
creation, since a sufficiently creative person can still obtain new
Example by calling
If you're doing something where you have to worry about this, Python
is probably the wrong language to write your code in.