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
__str__
and
__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
with
statements (instead of class instances) by implementing the context manager special methods on your metaclass. It's possible that there's some use for this.
Sidebar: why your metaclass must descend from
type
Armed with this understanding about special methods I can now explain the reason why metaclasses have to subclass
type
instead of
object
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
type
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 come from
object
;
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.)