Should All Python Classes Extend Object

Should all Python classes extend object?

In Python 2, not inheriting from object will create an old-style class, which, amongst other effects, causes type to give different results:

>>> class Foo: pass
...
>>> type(Foo())
<type 'instance'>

vs.

>>> class Bar(object): pass
...
>>> type(Bar())
<class '__main__.Bar'>

Also the rules for multiple inheritance are different in ways that I won't even try to summarize here. All good documentation that I've seen about MI describes new-style classes.

Finally, old-style classes have disappeared in Python 3, and inheritance from object has become implicit. So, always prefer new style classes unless you need backward compat with old software.

Why do Python classes inherit object?

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:

  1. "classic" style classes: they don't have object as a base class:

    >>> class ClassicSpam:      # no base class
    ... pass
    >>> ClassicSpam.__bases__
    ()
  2. "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:

    1. classmethod: A method that receives the class as an implicit argument instead of the instance.
    2. staticmethod: A method that does not receive the implicit argument self as a first argument.
    3. properties with property: Create functions for managing the getting, setting and deleting of an attribute.
    4. __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.

Do I need to inherit object in my Python classes?

This only matters if you are using Python 2, class Foo() will create an old-style class so I suggest you always use class Foo(object): to create a new-style class.

But if you are using Python 3, class Foo: is the same as class Foo(): and class Foo(object):, so you can use any of those because all of them will create a new-style class. I personally use the first one.

Is it necessary or useful to inherit from Python's object in Python 3.x?

You don't need to inherit from object to have new style in python 3. All classes are new-style.

Since all classes extend Object, and Object is a class, how can Object extend Object?

java.lang.Object is special in this way. The Java language specification, section 8.1.4 states:

The extends clause must not appear in the definition of the class Object, or a compile-time error occurs, because it is the primordial class and has no direct superclass.

If you look at any implementation of the Java standard library, you'll find that the source of java.lang.Object does in fact not have an extends clause (and because the Object class is primordial and has special treatment in the spec, there's no extends Object implicitly present).

Additionally, you may observe that the value of Object.class.getSuperclass() is precisely the null reference.

Digging into native code, it appears that this rule is enforced here, after a few layers of delegation.

How to inherit and extend class attributes in Python?

Subclasses never have their superclasses' attributes as their attributes, whether methods or not.

class Subclass(Super):
dictionary = Super.dictionary
dictionary.update({zero:0})

Why need to extends Object?

All dart classes implicitly extend Object, even if not specified.

This can be verified using the following code:

class Foo {}

void main() {
var foo = Foo();
print(foo is Object); // true
}

Even null implements Object, which allows doing:

null.toString()
null.hashCode
null == something

How to extend a class in python?

Use:

import color

class Color(color.Color):
...

If this were Python 2.x, you would also want to derive color.Color from object, to make it a new-style class:

class Color(object):
...

This is not necessary in Python 3.x.



Related Topics



Leave a reply



Submit