Imagine you’re doing a project. You went and downloaded a package you needed for it, and when you opened the package, what do you see? A file named __init__.py is present in it that no one told you about. Ever wondered what this file is used for or why these packages have it at all?
What is __init__ method in python?
__init__.py is a python file present in python packages. You can see an __init__.py in every python package. To understand __init__.py, first, we have to understand what the __init__ method does in python.
If you have used c++ before and are familiar with OOP in c++, you must know about constructor. A constructor is a member function of a class that is implicitly called whenever you create an object or an instance of a class. The purpose of a constructor is to initialize the data members in the class and allocate memory for the object when an object is created.
A constructor is an important part of a class. In fact, it’s so important that even if you don’t declare a constructor, the c++ compiler will implicitly declare one. __init__ is the constructor of a class in python. It initializes all the data members and allocates memory for the object of the class when an instance or object is created.
Related: Learn more about the __init__ method.
Understanding the purpose of __init__.py
__init__.py does the same thing that the __init__ method does but just for the directories instead of classes. You can imagine it as a constructor for a directory. Whenever we import a package the python interpreter searches for the __init__.py file in it and runs it first. The __init__.py file is an important part of the package. A regular package must have an __init__.py file in it even though it is empty just like a class has __init__ function in it.
Where is __init__.py used?
There are two types of packages in python, regular and namespace packages. A regular package is just a directory with an __init__.py file in it. Regular packages were in python 3.2 and previous versions and namespace packages were started from python version 3.3. The popular packages which you use in python on regular basis like numpy and pandas are examples of regular packages. A regular package can be nested with many layers of regular packages with each layer having an __init__.py file in it.
Let’s try to understand this with the help of an example.
In the above example, you can see there’s a package named Parent and it has sub-packages in it named Child1-B and Child1-C. We know it is a package cause it has __init__.py file in it. Now when we import the parent the interpreter searches for the __init__.py file in it, and implicitly runs the __init__.py file present in it. If we import child1-B, the interpreter will search for __init__.py in child1-B in it and run it. This way we can nest the regular packages by just adding __init__.py file in them.
In python 3.3 python introduced namespace packages. Namespace packages are packages in which some parts of packages may be present at various locations. A namespace package can contain virtual packages too. These namespace packages don’t require __init__.py. They can exist without __init__.py contradictory to regular packages which must have an __init__.py in them to be considered as a package by the python interpreter.
So the bottom line is __init__.py acts as a constructor for a regular package which can be empty but must be present in a regular package so that the python interpreter can identify it. The namespace packages, which are started from python version 3.3 can exist without __init__.py whereas it is necessary for a regular package to have an __init__.py file in it.
Related: Learn more about constructors in python.