import_that: XKCD guy flying with Python (Default)
[personal profile] import_that
One of the historical oddities of Python is that there are two different kinds of classes, so-called "classic" or "old-style" classes, and "new-style" classes or types. To understand the reason, we have to go back to the dawn of time and very early Python.

Back in the early Python 1.x days, built-in types like int, str and list were completely separate from classes you created with the class keyword. Built-in types were written in C, classes were written in Python, and the two could not be combined. So in Python 1.5, you couldn't inherit from built-in types:

>>> class MyInt(int):
...     pass
Traceback (innermost last):
  File "", line 1, in ?
TypeError: base is not a class object

If you wanted to inherit behaviour from a built-in type, the only way to do so was by using delegation, a powerful and useful technique that is unfortunately underused today. At the time though, it was the only way to solve the problem of subclassing from built-in types, leading to useful recipes like this one from Alex Martelli.

But in Python 2.2, classes were unified with built-in types. This involved a surprising number of changes to the behaviour of classes, so for backwards-compatibility, both the old and the new behaviour was kept. Rather than introduce a new keyword, Python 2.2 used a simple set of rules:

  • If you define a class that doesn't inherit from anything, it is an old-style classic class.

  • If your class inherits from another classic class, it too is a classic class.

  • But if you inherit from a built-in type (e.g. dict or list) then it is a new-style class and the new rules apply.

  • Since Python supports multiple inheritance, you might inherit from both new-style and old-style classes; in that case, your class will be new-style.

To aid with this, a new built-in type was created, object. object is the parent type of all new-style classes and types, but not old-style classes. Curiously, isinstance(classic_instance, object) still returns True, even though classic_instance doesn't actually inherit from object. At least that is the case in Python 2.4 and above, I haven't tested 2.2 or 2.3.

There are a few technical differences in behaviour between the old- and new-style classes, including:

  • super only works in new-style classes.

  • Likewise for classmethod and staticmethod.

  • Properties appear to work in classic classes, but actually don't. They seem to work so long as you only read from them, but if you assign to a property, the setter method is not called and the property is replaced.

  • In general, descriptors of any sort only work with new-style classes.

  • New-style classes support __slots__ as a memory optimization.

  • The rules for resolving inheritance of old- and new-style classes are slightly different, with old-style classes' method resolution order being inconsistent under certain circumstances.

  • New-style classes optimize operator overloading by skipping dunder methods like __add__ which are defined on the instance rather than the class.

The complexity of having two kinds of class was always intended to be a temporary measure, and in Python 3, classic classes were finally removed for good. Now, all classes inherit from object, even if you just write class MyClass: with no explicit bases.
Identity URL: 
Account name:
If you don't have an account you can create one now.
HTML doesn't work in the subject.


If you are unable to use this captcha for any reason, please contact us by email at

Notice: This account is set to log the IP addresses of everyone who comments.
Links will be displayed as unclickable URLs to help prevent spam.


import_that: XKCD guy flying with Python (Default)
Steven D'Aprano

May 2015

345678 9

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags