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 both new-style and traditional 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.
Although it has been discussed in earlier responses, here is an example of the distinction between old 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.
Only new-style classes are available in Python 3. Even if you write a ‘old-style class,’ it is inherited from object implicitly.
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