Problem
What is the difference between old and new style Python classes? When should I use one and when should I use the other?
Asked by readonly
Solution #1
From New-style and classic classes:
Answered by 10 revs, 7 users 53%
Solution #2
Declaration-wise:
Object or another new-style class can be inherited by new-style classes.
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
Old-style classes don’t.
class OldStyleClass():
pass
Python 3 Note:
Because Python 3 does not allow old-style classes, one of the following methods produces a new-style class.
Answered by Mark Harrison
Solution #3
There are significant behavioral differences between old and new type classes.
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).
In multiple inheritance, the order in which attributes (including methods and member variables) are searched for is the question.
Classic classes search from left to right in depth. On the first match, come to a halt. The __mro__ attribute is missing from them.
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
Classes in a new format In a single English statement, MRO is more difficult to synthesize. It is described in great detail here. One of its features is that a base class is only found after all of its derived classes have been found. They have an attribute called __mro__ that displays 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)
Many classes could be raised in Python 2.5, however this was eliminated in Python 2.6. On Python 2.7.3, do the following:
# 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
Answered by Ciro Santilli 新疆再教育营六四事件法轮功郝海东
Solution #4
For attribute lookup, old style classes are still slightly faster. This isn’t normally significant, but it can be handy in performance-critical situations. Python 2.x source 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
Answered by xioxox
Solution #5
Guido has produced The Inside Story on New-Style Classes, a fantastic piece discussing the differences between new-style and old-style Python classes.
Python 3 has only new-style class. Even if you write an ‘old-style class’, it is implicitly derived from object.
Super, the new C3 mro, several magical methods, and other advanced capabilities are available in new-style classes that are not available in old-style classes.
Answered by Xiao Hanyu
Post is based on https://stackoverflow.com/questions/54867/what-is-the-difference-between-old-style-and-new-style-classes-in-python