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
?
New-style classes were introduced in Python 2.2 to unify the concepts of class and type. A new-style class is simply a user-defined type, no more, no less. If x is an instance of a new-style class, then type(x) is typically the same as x.
Everything in Python is an object including classes. All classes are instances of a class called "type". The type object is also an instance of type class. You can inspect the inheritance hierarchy of class by examining the __bases__ attribute of a class object.
In Python, abstract base classes provide a blueprint for concrete classes. They don't contain implementation. Instead, they provide an interface and make sure that derived concrete classes are properly implemented. Abstract base classes cannot be instantiated.
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.
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!
You may find this and this posts interesting. Here's the diagram from the first:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With