Basic structure of the package
Let’s consider a package named operations, which contains modules for use in a calculator.py script:
Example: calculator.py (Main Script)
Output:
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:
Output:
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
Output:
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:
Output with __init__.py:
Output without __init__.py:
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:
Expected Behavior:
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:
Output
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
- 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.
- 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.