Python’s special __init__.py
file marks a directory as a regular Python package and allows you to import its modules. This file runs automatically the first time you import its containing package. You can use it to initialize package-level variables, define functions or classes, and structure the package’s namespace clearly for users.
By the end of this tutorial, you’ll understand that:
- A directory without an
__init__.py
file becomes a namespace package, which behaves differently from a regular package and may cause slower imports. - You can use
__init__.py
to explicitly define a package’s public API by importing specific modules or functions into the package namespace. - The Python convention of using leading underscores helps indicate to users which objects are intended as non-public, although this convention can still be bypassed.
- Code inside
__init__.py
runs only once during the first import, even if you run the import statement multiple times.
Understanding how to effectively use __init__.py
helps you structure your Python packages in a clear, maintainable way, improving usability and namespace management.
Note: The filename __init__.py
is hard to pronounce. Most people find it easier to call it dunder-init.
You may have seen files named __init__.py
scattered throughout large Python projects and wondered exactly what they do. Or you may have used __init__.py
files yourself without a clear idea of why they’re necessary or how to exploit their features. You might also have noticed that your Python code sometimes works even if you forget to add __init__.py
to your packages.
So, what is __init__.py
for?
Get Your Code: Click here to download the free sample code that shows you how to use Python’s __init__.py
.
Take the Quiz: Test your knowledge with our interactive “What Is Python's __init__.py For?” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
What Is Python's __init__.py For?Test your understanding of Python's __init__.py files to master how they shape your packages, enhance project structure, and keep your code clean.
In Short: __init__.py
Declares a Folder as a Regular Python Package
The special file __init__.py
serves as a marker to indicate that its containing directory is a regular package. When people talk about a package in Python, they generally mean a regular package. The __init__.py
file is a Python source file, which means that it’s also a module.
If you want to review the terms module and package and how they’re used in Python, then expand the collapsible section below:
In Python, the terms module and package both describe units containing code:
Module | Package | |
---|---|---|
Definition | A single Python file containing code | A directory containing one or more Python modules |
Naming | The filename without the .py extension |
The directory name |
Contents | Functions, classes, and variables | Modules and optionally subpackages |
Purpose | Organizing small projects, simple code reuse | Organizing large projects, code reuse |
Importing | Import directly (import module ) |
Import package or its modules (import package.module ) |
As you can see, modules and packages both help organize Python code, with modules representing single files and packages representing directories that can group multiple modules.
The existence of __init__.py
makes the Python loader identify its containing directory as a regular package. This means you can import the whole directory, specific modules within it, or even individual functions, variables, and classes from those modules using the package name.
You can also import those code objects into other modules, which allows your code to be reused in many flexible ways. You’ll see several examples of this shortly.
As mentioned, __init__.py
may be an empty file, in which case it serves only to identify a package.
What Happens When I Add Code to __init__.py
?
If __init__.py
does contain code, then that code will be executed when the package is first imported.
The code in __init__.py
can perform a variety of useful tasks. For example, it can import other modules or packages and define its own functions or data. When a package is imported, all of its own code, along with everything it has itself imported, becomes accessible to the importing module.
You’ll start with a simple example based on a single package. Here’s the setup:
tools_project/
│
└── tools/
└── __init__.py
So, your project is named tools_project
. It has a package named tools
. The tools/__init__.py
file could have been completely empty, but here it contains a few lines of code:
tools_project/tools/__init__.py
__version__ = "1.0.0"
magic_number = 42
With those files in place, start a REPL session in the tools_project
directory, and watch what happens when you import and use the tools
package:
1>>> import tools
2>>> tools.__version__
3'1.0.0'
4>>> tools.magic_number
542