DEV Community

Pila louis
Pila louis

Posted on

Constructors in Python (__init vs __new__)

Most object-oriented programming languages such as Java, C++, C#..etc have the concept of a constructor, a special method that creates and initializes the object when it is created. Python is a little different; it has a constructor and an initializer. The constructor function is rarely used unless you're doing something exotic. So, we'll start our discussion with the initialization method. 

The assumption in this article is that you already know the basics of classes and objects in python. 

The constructor function in python is called __new__ and __init__ is the initializer function.

Quoting the python documentation, __new__ is used when you need to control the creation of a new instance while __init__ is used when you need to control the initialization of a new instance.

__new__ is the first step of instance creation. It's called first and is responsible for returning a new instance of your class.

In contrast, __init__ doesn't return anything; it's only responsible for initializing the instance after it's been created. In general, you shouldn't need to override __new__unless you're subclassing an immutable type like str, int, Unicode, or tuple.

NOTE: 
Never name a function of your own with leading and trailing double underscores. It may mean nothing to Python, but there's always the possibility that the designers of Python will add a function that has a special purpose with that name in the future, and when they do, your code will break.

Example 1: Using __init__

class Point:

    def __init__(self, data):
        self.num = data

    def print_num(self):
        print(self.num)



obj = Point(100)

obj.print_num()

Output:

100

Note: The self parameter is a reference to the current instance of the class and is used to access variables that belong to the class.

Example 2:

class Person:

    def __new__(cls):
        return object.__new__(cls)

    def __init__(self):
        self.instance_method()

    def instance_method(self):
        print('success!')

personObj = Person()

Notice that __init__ receives the argument self, while __new__ receives the class (cls). Since self is a reference to the instance, this should tell you quite evidently that the instance is already created by the time __init__ gets called, since it gets passed the instance. It's also possible to call instance methods precisely because the instance has already been created.

Thank you for reading. 😄
END!!!

Top comments (2)

Collapse
 
stevenlu2004 profile image
Tongyu Lu • Edited

You can actually use

super().method_name(*args, **kw)  # PEP 3135
Enter fullscreen mode Exit fullscreen mode

In this case, it can be

super().__new__(cls, *args, **kw)
Enter fullscreen mode Exit fullscreen mode

The cls is actually necessary for __new__.

See more about PEP 3135 →