Reputation: 18585
According to the doc, object
is all new-style classes' base class.
And AFAIK, the so-called new-style classes are just ones which can acquire some new fetures by inheriting object
, right?
I thought object
inherit type
or use type
as its __metaclass__
, but object.__bases__
gives me nothing, so where dose this object
come from, and what's relationship bewteen it and type
?
Upvotes: 5
Views: 2503
Reputation: 184220
Indeed, the type (i.e., metaclass) of object
, a class, is type
:
type(object) == type # True
And since object
is the base class, it has no parents of its own, as you'd expect:
object.__bases__ == () # True
object
doesn't have a __metaclass__
attribute because it doesn't need one: it uses the default metaclass, type
.
Now it's a little confusing because type
is in fact a subclass of object
, which boggles the mind (how can type
be derived from object
when you need type
to construct object
?) but this is solved by a little hard-coding at the C level in the Python interpreter.
All this applies only to new-style classes, that is, those derived from object
. In Python 3, all classes are new-style, so this applies globally in Python 3.
Upvotes: 5
Reputation: 273616
You may find this and this posts interesting. Here's the diagram from the first:
Upvotes: 2
Reputation: 43051
There are two concepts that could be helpful to keep in mind:
__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!
Upvotes: 3