__init__ v.s __new__
__init__ and __new__ are both special methods in Python, but they serve different purposes.
__new__
The __new__ method is a static method that is responsible for creating a new instance of the class. It is the first step of object creation and it's called before __init__. It takes the class and other arguments from which it creates an instance, and returns this new instance. You generally don't need to override __new__ unless you're doing something very specific with object creation.[1]
def __new__(cls, *args, **kwargs):
__init__
The __init__ method is an instance method that prepares the new instance for use, typically by initializing its attributes. It is called after the instance has been created (by __new__), allowing you to customize the object state upon creation.
def __init__(self, *args, **kwargs):
Summary
In summary, __new__ is for creating and returning a new instance, and __init__ is for customizing the state of that new instance. In most cases, you only need to use __init__.