What is the __init__.py file in Python?

What is the __init__.py file in Python?

In Python, __init__.py is a special file that allows Python to know that a folder is a package. This helps organize your code and manage how different parts of your program are imported. It lets you add setup code, control imports, and define package behavior. It’s useful when building larger projects with multiple modules. In this blog, you’ll learn the purpose, use cases, and importance of __init__.py in Python projects.

Table of Contents:

Understanding __init__.py in Python

The __init__.py file in Python is a key building block for creating a structured and organized package for Python. It binds your code together so it becomes easier for it to be managed, reused, and eventually shared. The __init__.py file can also be used for several helpful tasks that make your package more powerful and easier to manage, and help in reusing the code easily by grouping related modules together.

Use of __init__.py in Python

  • The file signals to Python that a directory needs to be treated as a package.
  • The file can execute an initialization code, meaning it includes a setup logic that is executed upon package import.
  • This file also controls the namespace exposure. Hence, it defines the available module when using from the package import *.
  • This file also facilitates structured access to submodules.

Basic structure of the package

Let’s consider a package named operations, which contains modules for use in a calculator.py script:

structure of the package

Example: calculator.py (Main Script)

Python

Output:

calculator

Explanation: This script imports the multiplier and divider modules from the operations package and also creates instances for the respective classes and calls them.

Operations/multiplier.py: Write the following code in the multiplier.py file

class Multiplier:
    def multiply(self, a, b):
          return a * b

Example:

Python

Output:

multiplier

Explanation: Here, the method multiply(self, a, b) gets input as two arguments (a and b). It returns the product of those two numbers using the * operator. This class is useful for covering multiplication logic, so it can be imported and reused anywhere in your project.

Operations/divider.py: Write the following code in the divider.py file

class Divider:
    def divide(self, a, b):
          return a / b

Example 

Python

Output:

divider

Explanation: Here, the divide(self, a, b) method takes two arguments. This will return the results of dividing a by b using the / operator. Division logic can be accessed cleanly from other parts of the program.

Operations/__init__.py

At first, the file remains empty to allow the directory to function as a package. In earlier versions of Python (before 3.3), excluding this file meant the directory wasn’t recognized as a package and couldn’t be imported.

Effects of __init__.py in Python

In the above example, the __init__.py file does the job of marking the operations folder as a package so Python can import its modules. This file also runs initialization code and defines __all__ to control what modules are accessible when using imports.  Even in recent versions of Python, __init__.py tends to affect package behavior. Thefollowing outputs and example will show the effect of the presence and absence of __init__.py.

Example:

Python

Output with __init__.py: 

Output with __init__

Output without __init__.py: 

Output without __init_

Explanation: The operations directory is treated as a namespace package, and when the  __init__.py file is missing, the package is treated as a namespace package, and attributes like __file__ may not be set or behave differently compared to regular packages.

Running Initialization Code in __init__.py in Python

When you import the package, the executable code inside __init__.py proceeds to run:

Python

Expected Behavior:

Running Initialization Code in __init__

Explanation: The statement inside __init__.py is executed by the print statement immediately when
the module is imported. This function is useful for setting up logging, global variables, or configurations.

Controlling import* with __all__ in Python

Example:

Python

Output

Controlling import with __all__

Explanation: Here, without using __all__, from operations import * won’t import modules like multiplier or divider. By defining __all__ in the __init__.py file, it specifies which modules should be included when using import *. This ensures that only the necessary parts of the package are exposed, keeping the code clean and organized.

Real-World Use Cases for __init__.py in Python

  1. Creating a plug-and-play package in Python: __init__.py can help you organize internal modules and expose a clean external interface for users. Especially when you are building a reusable package, for example, math operations and data utilities.
  1. Managing Shared Configurations: In the case of database connections and logging setups, the multiple submodules in these instances rely on the same settings. Here, you can place the configuration logic in the __init__.py file, ensuring it initializes once the package is imported.

Best Practices for Using __init__.py File in Python

  • Make sure to include __init__.py for backward compatibility: for consistent behavior across all environments and versions, it is better to include the file in your code.
  • Utilize it to initialize package-wide settings: It is a good habit to put setup logic like environment variables, logging configurations, or shared constants directly inside the __init__.py file.
  • Remember to use __all__ to control what is getting imported: Define __all__ = [‘module1’, ‘module2’] to manage what’s imported when someone uses from package import *.
  • Keep the file lightweight: Better to avoid putting too much logic code in the __init__.py file. Give it logic that focuses on initialization and delegates business to other modules.
  • Expose a clean interface: You can import key classes or functions into __init__.py to flatten your API. Run the command from .multiplier import Multiplier, and in the next line from .divider import Divider, this allows usage like from operations import Multiplier, Divider.

Conclusion

In Python, the __init__.py defines a package while controlling import behavior. It also allows execution of the package initialization code and helps manage the module that is exposed when using wildcard imports. Starting with Python 3.3, __init__.py is not required to make a folder a package, but it’s still good to include it for clarity and to support older versions.

Further, upgrade your Python skills by visiting a Python certification course and get ready to excel in your career with  Basic Python interview questions prepared by experts.

What is __init__.py file in Python – FAQs

Q1. Is the file __init__.py mandatory in Python 3?

No, this file is not mandatory, but it helps in structuring packages and in managing imports explicitly.

Q2. What would happen if __init__.py is missing in the Python directory?

Python will still recognize the directory as a namespace package, but change behavior in module resolution and metadata.

Q3. Can the __init__.py file contain executable code?

Yes, it can contain executable code and define variables, run setup logic, etc.

Q4. How does __all__ affect package imports in Python?

Its basic function is to control submodules that get imported using from package import *.

Q5. Give me a way to create an empty __init__.py file.

Use the method touch operations/__init__.py, this will ensure backward compatibility and explicit package behavior.

About the Author

Senior Consultant Analytics & Data Science, Eli Lilly and Company

Sahil Mattoo, a Senior Software Engineer at Eli Lilly and Company, is an accomplished professional with 14 years of experience in languages such as Java, Python, and JavaScript. Sahil has a strong foundation in system architecture, database management, and API integration. 

Full Stack Developer Course Banner