What is the difference between old style and new style classes in Python?

PythonClassOopTypesNew Style-Class

Python Problem Overview


What is the difference between old style and new style classes in Python? When should I use one or the other?

Python Solutions


Solution 1 - Python

From New-style and classic classes:

> Up to Python 2.1, old-style classes were the only flavour available to the user. > > The concept of (old-style) class is unrelated to the concept of type: > if x is an instance of an old-style class, then x.__class__ > designates the class of x, but type(x) is always <type > 'instance'>. > > This reflects the fact that all old-style instances, independently of > their class, are implemented with a single built-in type, called > instance. > >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.__class__ (although this is not guaranteed – a > new-style class instance is permitted to override the value returned > for x.__class__). > >The major motivation for introducing new-style classes is to provide a unified object model with a full meta-model. > > It also has a number of immediate benefits, like the ability to > subclass most built-in types, or the introduction of "descriptors", > which enable computed properties. > >For compatibility reasons, classes are still old-style by default. > > New-style classes are created by specifying another new-style class > (i.e. a type) as a parent class, or the "top-level type" object if no > other parent is needed. > > The behaviour of new-style classes differs from that of old-style > classes in a number of important details in addition to what type > returns. > > Some of these changes are fundamental to the new object model, like > the way special methods are invoked. Others are "fixes" that could not > be implemented before for compatibility concerns, like the method > resolution order in case of multiple inheritance. > >Python 3 only has new-style classes. > > No matter if you subclass from object or not, classes are new-style > in Python 3.

Solution 2 - Python

Declaration-wise:

New-style classes inherit from object, or from another new-style class.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

Old-style classes don't.

class OldStyleClass():
    pass

Python 3 Note:

Python 3 doesn't support old style classes, so either form noted above results in a new-style class.

Solution 3 - Python

Important behavior changes between old and new style classes

  • super added
  • MRO changed (explained below)
  • descriptors added
  • new style class objects cannot be raised unless derived from Exception (example below)
  • __slots__ added

MRO (Method Resolution Order) changed

It was mentioned in other answers, but here goes a concrete example of the difference between classic MRO and C3 MRO (used in new style classes).

The question is the order in which attributes (which include methods and member variables) are searched for in multiple inheritance.

Classic classes do a depth-first search from left to right. Stop on the first match. They do not have the __mro__ attribute.

class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 0
assert C21().i == 2

try:
    C12.__mro__
except AttributeError:
    pass
else:
    assert False

New-style classes MRO is more complicated to synthesize in a single English sentence. It is explained in detail here. One of its properties is that a base class is only searched for once all its derived classes have been. They have the __mro__ attribute which shows the search order.

class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 2
assert C21().i == 2

assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)

New style class objects cannot be raised unless derived from Exception

Around Python 2.5 many classes could be raised, and around Python 2.6 this was removed. On Python 2.7.3:

# OK, old:
class Old: pass
try:
    raise Old()
except Old:
    pass
else:
    assert False

# TypeError, new not derived from `Exception`.
class New(object): pass
try:
    raise New()
except TypeError:
    pass
else:
    assert False

# OK, derived from `Exception`.
class New(Exception): pass
try:
    raise New()
except New:
    pass
else:
    assert False

# `'str'` is a new style object, so you can't raise it:
try:
    raise 'str'
except TypeError:
    pass
else:
    assert False

Solution 4 - Python

Old style classes are still marginally faster for attribute lookup. This is not usually important, but it may be useful in performance-sensitive Python 2.x code:

In [3]: class A:
...:     def init(self):
...:         self.a = 'hi there'
...:

In [4]: class B(object): ...: def init(self): ...: self.a = 'hi there' ...:

In [6]: aobj = A() In [7]: bobj = B()

In [8]: %timeit aobj.a 10000000 loops, best of 3: 78.7 ns per loop

In [10]: %timeit bobj.a 10000000 loops, best of 3: 86.9 ns per loop

Solution 5 - Python

Guido has written The Inside Story on New-Style Classes, a really great article about new-style and old-style class in Python.

Python 3 has only new-style class. Even if you write an 'old-style class', it is implicitly derived from object.

New-style classes have some advanced features lacking in old-style classes, such as super, the new C3 mro, some magical methods, etc.

Solution 6 - Python

Here's a very practical, true/false difference. The only difference between the two versions of the following code is that in the second version Person inherits from object. Other than that, the two versions are identical, but with different results:

  1. Old-style classes

    class Person():
        _names_cache = {}
        def __init__(self,name):
            self.name = name
        def __new__(cls,name):
            return cls._names_cache.setdefault(name,object.__new__(cls,name))
    
    ahmed1 = Person("Ahmed")
    ahmed2 = Person("Ahmed")
    print ahmed1 is ahmed2
    print ahmed1
    print ahmed2
    
    
    >>> False
    <__main__.Person instance at 0xb74acf8c>
    <__main__.Person instance at 0xb74ac6cc>
    >>>
    
    
  2. New-style classes

    class Person(object):
        _names_cache = {}
        def __init__(self,name):
            self.name = name
        def __new__(cls,name):
            return cls._names_cache.setdefault(name,object.__new__(cls,name))
    
    ahmed1 = Person("Ahmed")
    ahmed2 = Person("Ahmed")
    print ahmed2 is ahmed1
    print ahmed1
    print ahmed2
    
    >>> True
    <__main__.Person object at 0xb74ac66c>
    <__main__.Person object at 0xb74ac66c>
    >>>
    

Solution 7 - Python

New-style classes inherit from object and must be written as such in Python 2.2 onwards (i.e. class Classname(object): instead of class Classname:). The core change is to unify types and classes, and the nice side-effect of this is that it allows you to inherit from built-in types.

Read http://www.python.org/download/releases/2.2.3/descrintro/">descrintro</a> for more details.

Solution 8 - Python

New style classes may use super(Foo, self) where Foo is a class and self is the instance.

> super(type[, object-or-type]) > > Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.

And in Python 3.x you can simply use super() inside a class without any parameters.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionreadonlyView Question on Stackoverflow
Solution 1 - PythonMark CidadeView Answer on Stackoverflow
Solution 2 - PythonMark HarrisonView Answer on Stackoverflow
Solution 3 - PythonCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 4 - PythonxioxoxView Answer on Stackoverflow
Solution 5 - PythonXiao HanyuView Answer on Stackoverflow
Solution 6 - PythonychaoucheView Answer on Stackoverflow
Solution 7 - PythonHaloView Answer on Stackoverflow
Solution 8 - PythonjamylakView Answer on Stackoverflow