Why do Python classes inherit object?
Solution 1:
Is there any reason for a class declaration to inherit from
object
?
In Python 3, apart from compatibility between Python 2 and 3, no reason. In Python 2, many reasons.
Python 2.x story:
In Python 2.x (from 2.2 onwards) there's two styles of classes depending on the presence or absence of object
as a base-class:
-
"classic" style classes: they don't have
object
as a base class:>>> class ClassicSpam: # no base class ... pass >>> ClassicSpam.__bases__ ()
-
"new" style classes: they have, directly or indirectly (e.g inherit from a built-in type),
object
as a base class:>>> class NewSpam(object): # directly inherit from object ... pass >>> NewSpam.__bases__ (<type 'object'>,) >>> class IntSpam(int): # indirectly inherit from object... ... pass >>> IntSpam.__bases__ (<type 'int'>,) >>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object (<type 'object'>,)
Without a doubt, when writing a class you'll always want to go for new-style classes. The perks of doing so are numerous, to list some of them:
-
Support for descriptors. Specifically, the following constructs are made possible with descriptors:
-
classmethod
: A method that receives the class as an implicit argument instead of the instance. -
staticmethod
: A method that does not receive the implicit argumentself
as a first argument. - properties with
property
: Create functions for managing the getting, setting and deleting of an attribute. -
__slots__
: Saves memory consumptions of a class and also results in faster attribute access. Of course, it does impose limitations.
-
The
__new__
static method: lets you customize how new class instances are created.Method resolution order (MRO): in what order the base classes of a class will be searched when trying to resolve which method to call.
Related to MRO,
super
calls. Also see,super()
considered super.
If you don't inherit from object
, forget these. A more exhaustive description of the previous bullet points along with other perks of "new" style classes can be found here.
One of the downsides of new-style classes is that the class itself is more memory demanding. Unless you're creating many class objects, though, I doubt this would be an issue and it's a negative sinking in a sea of positives.
Python 3.x story:
In Python 3, things are simplified. Only new-style classes exist (referred to plainly as classes) so, the only difference in adding object
is requiring you to type in 8 more characters. This:
class ClassicSpam:
pass
is completely equivalent (apart from their name :-) to this:
class NewSpam(object):
pass
and to this:
class Spam():
pass
All have object
in their __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
So, what should you do?
In Python 2: always inherit from object
explicitly. Get the perks.
In Python 3: inherit from object
if you are writing code that tries to be Python agnostic, that is, it needs to work both in Python 2 and in Python 3. Otherwise don't, it really makes no difference since Python inserts it for you behind the scenes.
Solution 2:
Python 3
-
class MyClass(object):
= New-style class -
class MyClass:
= New-style class (implicitly inherits fromobject
)
Python 2
-
class MyClass(object):
= New-style class -
class MyClass:
= OLD-STYLE CLASS
Explanation:
When defining base classes in Python 3.x, you’re allowed to drop the object
from the definition. However, this can open the door for a seriously hard to track problem…
Python introduced new-style classes back in Python 2.2, and by now old-style classes are really quite old. Discussion of old-style classes is buried in the 2.x docs, and non-existent in the 3.x docs.
The problem is, the syntax for old-style classes in Python 2.x is the same as the alternative syntax for new-style classes in Python 3.x. Python 2.x is still very widely used (e.g. GAE, Web2Py), and any code (or coder) unwittingly bringing 3.x-style class definitions into 2.x code is going to end up with some seriously outdated base objects. And because old-style classes aren’t on anyone’s radar, they likely won’t know what hit them.
So just spell it out the long way and save some 2.x developer the tears.
Solution 3:
Yes, this is a 'new style' object. It was a feature introduced in python2.2.
New style objects have a different object model to classic objects, and some things won't work properly with old style objects, for instance, super()
, @property
and descriptors. See this article for a good description of what a new style class is.
SO link for a description of the differences: What is the difference between old style and new style classes in Python?