There are two concepts that could be helpful to keep in mind:
- everything in python is an object, including classes and metaclasses
- metaclasses are the constructors of classes, not their ancestors, so they do not appear in
__bases__
.
That means that object
indeed has type
as metaclass.
Just as a curiosity, the "paradoxical" part of the story is the type
, which being a metaclass is also an object, but can't have itself as metaclass (it would be a bit of chicken-and-egg problem, if you think about it).
The paradox is solved with some C voodoo in the python source code, but I don't know much about it!
EDIT: (some example code)
>>> class MyMeta(type):
... def __new__(cls, name, bases, dct):
... return type.__new__(cls, name, bases, dct)
...
>>> class MyClass(object):
... __metaclass__ = MyMeta
...
Now observe that obj
inherit from object
>>> obj = MyClass()
>>> MyClass.__bases__
(<type 'object'>,)
As for your question in the comments about dir(obj)
doesn't output the __metaclass__
attribute: the reason is that __metaclass__
is an attribute of the class not of its instantiated object. Note in fact that:
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> MyClass.__metaclass__
<class '__main__.MyMeta'>
If you are interested in deepening your understanding of metaclasses, this is a classic SO question (with a very comprehensive answer, of course!):
What is a metaclass in Python?
HTH!