patternpythonCritical
Why do Python classes inherit object?
Viewed 0 times
whyobjectpythoninheritclasses
Problem
Why does the following class declaration inherit from
object?class MyClass(object):
...Solution
Is there any reason for a class declaration to inherit from
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
-
"classic" style classes: they don't have
-
"new" style classes: they have, directly or indirectly (e.g inherit from a built-in type),
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:
-
The
-
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,
If you don't inherit from
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
is completely equivalent (apart from their name :-) to this:
and to this:
All have
So, what should you do?
In Python 2: always inherit from
In Python 3: 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__
(,)
>>> class IntSpam(int): # indirectly inherit from object...
... pass
>>> IntSpam.__bases__
(,)
>>> IntSpam.__bases__[0].__bases__ # ... because int inherits from 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 argumentselfas 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:
passis completely equivalent (apart from their name :-) to this:
class NewSpam(object):
passand to this:
class Spam():
passAll 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.Code Snippets
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()>>> 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'>,)class ClassicSpam:
passclass NewSpam(object):
passclass Spam():
passContext
Stack Overflow Q#4015417, score: 1265
Revisions (0)
No revisions yet.