An operational explanation of Python metaclasses (part 4)
The metaclass use of
__call__ that I covered in part 2 and the use of
__getattribute__ et al that I
mentioned in part 3 are both specific instances of
a general metaclass power: a metaclass supplies the special methods
for its classes. However and as before, these special methods apply
only when you are looking at or manipulating the class itself, not when
you are dealing with instances of the class.
(Special methods for instances of the class have to be supplied by the class or an ancestor it inherits from, as usual.)
Most special methods aren't particularly useful for classes, since you rarely want to do things like treat a class object as a sequence; usually classes just sort of sit there being instantiated and subclassed. The useful special methods are the handful of methods that affect things that you use classes for, which means that part 2 and part 3 have already covered most of them.
(While you can define custom
__repr__ methods in
a metaclass, note that these methods are not used when printing the
class name portion of an instance of a class; you still get the familiar
<file.whatever object at 0x...>' result unless you have appropriate
custom methods on the class itself.)
There are two additional sets of special methods that are worth
mention. First, you can control how subclassing and instance checks
work; this is covered in the Python documentation on Customizing
instance and subclass checks,
which explicitly mentions that these methods have to be defined in
a metaclass. Second, you can use bare classes in
(instead of class instances) by implementing the context manager
on your metaclass. It's possible that there's some use for this.
Sidebar: why your metaclass must descend from
Armed with this understanding about special methods I can now explain
the reason why metaclasses have to subclass
type instead of
and why you get strange error messages if you don't, as I mentioned in
passing in part 1. We can see the answer by asking
'what is the metaclass of a class without a metaclass?'
The answer is '
type'. Given that your metaclass supplies
implementations of special methods, this means that
type supplies the
default versions of things like
__call__. If you subclass
in your metaclass, you inherit all of the necessary default versions
of various special methods. If you don't, well, they aren't going to
object doesn't supply them. This is also why
you need to call up to
type (either via
super() or directly) in
order to get various things done in a metaclass;
type does all of the
magic necessary to actually create new classes, call them to create new
instances of them, and so on.
(Yes, technically a metaclass can be any callable not just a class. I'm looking only at the 'metaclass as a class' case right now.)