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

In Python, there are two styles of classes that differ based on their inheritance from built-in types. Understanding this distinction is important when working with Python 2.x code or legacy systems.

Old Style Classes

Old style classes (also called "classic" classes) have no built-in type as a base class. They were the default in Python 2.x when no explicit inheritance was specified ?

class OldSpam:    # no base class
    pass

print(OldSpam.__bases__)
()

New Style Classes

New style classes have a built-in type as a base class, meaning they directly or indirectly inherit from object ?

# Direct inheritance from object
class NewSpam(object):
    pass

print(NewSpam.__bases__)

# Indirect inheritance through int (which inherits from object)
class IntSpam(int):
    pass

print(IntSpam.__bases__)
print(IntSpam.__bases__[0].__bases__)
(<type 'object'>,)
(<type 'int'>,)
(<type 'object'>,)

Advantages of New Style Classes

New style classes provide several important features that old style classes lack ?

Descriptors Support

New style classes enable the following descriptor-based constructs ?

  • classmethod ? A method that receives the class as an implicit argument instead of the instance
  • staticmethod ? A method that does not receive the implicit argument self as a first argument
  • properties ? Create functions for managing getting, setting and deleting attributes using property()
class Person(object):
    def __init__(self, name):
        self._name = name
    
    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        self._name = value
    
    @classmethod
    def from_string(cls, name_str):
        return cls(name_str)
    
    @staticmethod
    def is_valid_name(name):
        return isinstance(name, str) and len(name) > 0

# Using the class
person = Person("Alice")
print(person.name)

person.name = "Bob"
print(person.name)

new_person = Person.from_string("Charlie")
print(new_person.name)

print(Person.is_valid_name("David"))
Alice
Bob
Charlie
True

Python 3.x Behavior

Python 3.x only supports new style classes implicitly. All classes automatically inherit from object even without explicit declaration ?

class ModernClass:    # automatically inherits from object
    pass

print(ModernClass.__bases__)
print(ModernClass.__mro__)  # Method Resolution Order
(<class 'object'>,)
(<class '__main__.ModernClass'>, <class 'object'>)

Comparison

Feature Old Style Classes New Style Classes
Inheritance from object No Yes
Descriptors (property, classmethod, staticmethod) No Yes
Method Resolution Order (MRO) Depth-first C3 linearization
Python 3.x support No Yes (default)

Conclusion

Always use new style classes by inheriting from object in Python 2.x, or simply define classes normally in Python 3.x. New style classes provide essential features like descriptors and improved method resolution that make them superior to old style classes.

Updated on: 2026-03-24T19:44:30+05:30

733 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements