If you’re familiar with OOP, I’m sure that you have already heard of constructors - a special method used to create and initialize a new instance of a given class. In Python, when defining a new class, an __init__ method is usually declared to initialize the attributes of the class.

class Example:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

The interesting thing is that while other object-oriented programming languages have a constructor method that both creates a new instance and initializes it, Python has two different methods for this:

  • __new__: called first and responsible for returning a new instance of the class
  • __init__: doesn’t return anything, it’s only responsible for initializing the instance after it has been created

Note that while the __init__ method receives the argument self, the __new__ method receives the class (cls). Receiving self as an argument implies that a new object has already been created by the time __init__ is called. On the other hand, the class (cls) can be used to create a new object (e.g. object.__new__(cls)).

class Example:
    def __init__(self):
        ...

    def __new__(cls):
        ...