Should all Python classes extend object?

56,155

Solution 1

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.

Solution 2

In Python 3, classes extend object implicitly, whether you say so yourself or not.

In Python 2, there's old-style and new-style classes. To signal a class is new-style, you have to inherit explicitly from object. If not, the old-style implementation is used.

You generally want a new-style class. Inherit from object explicitly. Note that this also applies to Python 3 code that aims to be compatible with Python 2.

Solution 3

In python 3 you can create a class in three different ways & internally they are all equal (see examples). It doesn't matter how you create a class, all classes in python 3 inherits from special class called object. The class object is fundamental class in python and provides lot of functionality like double-underscore methods, descriptors, super() method, property() method etc.

Example 1.

class MyClass:
 pass

Example 2.

class MyClass():
 pass

Example 3.

class MyClass(object):
  pass

Solution 4

Yes, all Python classes should extend (or rather subclass, this is Python here) object. While normally no serious problems will occur, in some cases (as with multiple inheritance trees) this will be important. This also ensures better compatibility with Python 3.

Solution 5

As other answers have covered, Python 3 inheritance from object is implicit. But they do not state what you should do and what is convention.

The Python 3 documentation examples all use the following style which is convention, so I suggest you follow this for any future code in Python 3.

class Foo:
    pass

Source: https://docs.python.org/3/tutorial/classes.html#class-objects

Example quote:

Class objects support two kinds of operations: attribute references and instantiation.

Attribute references use the standard syntax used for all attribute references in Python: obj.name. Valid attribute names are all the names that were in the class’s namespace when the class object was created. So, if the class definition looked like this:

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

Another quote:

Generally speaking, instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class:

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance
Share:
56,155
Kara
Author by

Kara

Software Developer with experience in: Python Lua iPhone/iPad Development PHP/MySQL

Updated on March 17, 2020

Comments

  • Kara
    Kara over 4 years

    I have found that both of the following work:

    class Foo():
        def a(self):
            print "hello"
    
    class Foo(object):
        def a(self):
            print "hello"
    

    Should all Python classes extend object? Are there any potential problems with not extending object?

  • max k.
    max k. over 11 years
    exactly, technically if you don't you will get a classic class, but there are no real advantages to this and it isn't supported by python 3 anyway
  • Paul Lo
    Paul Lo almost 10 years
    I'm curious about why it improve compatibility with python3. To my understanding, python3 will make it extend object automatically even if u don't specify it, right?
  • pydsigner
    pydsigner about 9 years
    @PaulLo Right, but if you explicitly inherit from object, you will get the same (new-style) behavior on both Python 2 and Python 3. It isn't a matter of changing how Python 3 works, it's a matter of using forward-compatibility on Python 2.
  • Mark Amery
    Mark Amery over 8 years
    This answer is reasonable, but other answerers got there faster and/or in better detail; this answer isn't adding any value to the page as it stands.
  • Wolf
    Wolf almost 8 years
    Yes, the difference Free Foo pointed out, has gone, BTW: are the empty parentheses optional?
  • Wolf
    Wolf almost 8 years
    This suggestion looks not very elegant, but in case you address Python2 and Python3, it seems effective. But how relevant is it in practice?
  • pydsigner
    pydsigner almost 8 years
    @Wolf It depends on what you're doing. If you have complex inheritance trees, it matters quite a lot. If you want your class to be a descriptor, you have to use new-style. You can follow the links from stackoverflow.com/questions/54867/… if you want more in-depth information.
  • RFV
    RFV over 7 years
    There is a lot of python 3 code that uses foo(object):. Is this just a convention then?
  • blubberdiblub
    blubberdiblub over 7 years
    @RFVenter It may be code that's supposed to run under both Python 2 and 3, in which case you need to subclass object explicitly in order to make the class behave largely the same under Python 2.
  • RFV
    RFV over 7 years
    @blubberdiblub That is what I suspected BUT our project is running exclusively on python 3.5 virtualenv. I think the code must have been copied from a python 2 project.
  • blubberdiblub
    blubberdiblub over 7 years
    @RFVenter yup, that may be another explanation. And of course, if it's Python 3.x only now, it's fine to get rid of the object references.
  • Philip Adler
    Philip Adler almost 7 years
    This is not strictly true... stackoverflow.com/questions/1238606/…
  • Philip Adler
    Philip Adler almost 7 years
    I'm not sure I follow you. And yes, probably not relevant to most people up until it is relevant.
  • Nuno André
    Nuno André over 5 years
    @PhilipAdler It's commonly assumed that object makes reference to built-in object. If we must take into account that any CPython's built-in identifier can be replaced we could barely make some assertion about the data model. Can it be seriously argued that str does not always accept a string as an argument because one could assign builtins.str = None?
  • Philip Adler
    Philip Adler over 5 years
    I keep seeing this claim that this is "widely assumed", and I accept that it is an assumption that every current implementation makes (it is not a requirement of the language), it has not been my experience that the majority of python programmers I have met assume this, know about it, or have even considered it. Regardless of which, the assertion that it is commonly assumed, even if true, does not invalidate my assertion that the equivalence is not strictly true.