Search code examples
pythonmetaclassmethod-resolution-order

Method resolution order and metaclasses


How come a metaclass does not show up in the MRO?

For instance:

>>> class Foo(type):
...  foo = 21
... 
>>> class Bar(metaclass=Foo):
...  pass
... 
>>> Bar.mro()
[<class '__main__.Bar'>, <class 'object'>]
>>> Bar.foo
21

Also, I saw elsewhere that Python uses C3 linearization to compute the MRO, but this linearization does not handle metaclasses. So what algorithm does Python use in that case?


Solution

  • Because none of your classes derive from the metaclass. A metaclass is not a base class. The metaclass is the factory that produced the Bar class object, just like a class object produces instances.

    There is no linearisation required here. Bar is an object of type Foo, just like other classes are of type type. Any subclasses of Bar will have the same type (the metaclass); they have that relationship directly. A class can have only one metaclass at a time.

    A metaclass comes last when looking up attributes; so Bar.spam will first be looked for in the MRO, and only then on type(Bar).

    Of course, metaclasses use an inheritance hierarchy too; Foo was derived from type in your example. That relationship uses an MRO too.