Friends, today we will talk about a low-key but crucial document in Python-__init__.py
。
To be honest, when I first started learning Python, many people (including me back then) were confused: "What? What will happen if I delete it?"
Some people may have heard that it is a "sign of the package", some people think it is "useless and can be ignored", and some people think it is "just a pretend document". Today, let's figure it out thoroughly__init__.py
What exactly does it do and how it affects the structure and operation of a Python project.
Understand Python module first
Chatting__init__.py
Before, we have to figure out what is in PythonModuleandBagThese two concepts.
module: Simply put, it is just one.py
File, some functions, classes or variables are written in it.
For example, there is a namemath_tools.py
The file contains a bunch of mathematical tool functions, and it is a module.
# math_tools.py def add(a, b): return a + b def subtract(a, b): return a - b
Then, we can use it like this in other Python files:
import math_tools print(math_tools.add(3, 5)) # Output 8
This isBasic usage of modules, nothing is difficult, right?
What is a Python package?
If you write more and more modules and the amount of code is getting bigger and bigger, you have to find a way to organize them. At this time, in PythonPackageIt comes in handy.
Package:oneFolders, contains multiple modules (.py
document).
existBefore Python 3.3, if you want a directory to be recognized as a Python package, you must create it inside__init__.py
document.But starting with Python 3.3, even if not__init__.py
, Python can also recognize it as a package (called a "namespace package").
However, most actual projectsStill recommend adding__init__.py
, because it can:
✅ Make sure that this folder is a package to avoid errors in identifying certain tools (such as packaging tools).
✅ Allows execution of specific code when package initialization, such as automatic import of submodules.
✅ Make import behavior more controllable and avoid unexpected naming conflicts.
For example, we have onemath_utils
The directory contains several math-related modules:
math_utils/ # This folder is a package
│── __init__.py
│──
│──
in,and
They are two modules,
__init__.py
Can be usedCustom package import behavior。
So what is __init__.py for?
Although__init__.py
No longer creating packagesRequiredcondition, but it is still an important component in Python projects.
Its main functions aretwo:
1. Clearly mark the directory as a Python package
if__init__.py
If it exists, the Python parser will know:"This directory is a Python package, not a normal folder."
Even if Python 3.3+ is not mandatory__init__.py
, but plus it can:
✅ Avoid the Python interpreter mistakenly considering it to be a normal directory in some cases.
✅ Compatible with old versions of Python, allowing the code to run more stably in different environments.
✅ Make certain tools (such aspytest
、mypy
) Better identify project structure.
2. Make the package be imported like a module
if__init__.py
If you don’t write anything in it, then its function is just a “sign”. But if we are__init__.py
Add some code to it and it canCustom package import behavior。
Example 1: Let the package expose the submodule directly
# math_utils/__init__.py from .basic import add, subtract from .advanced import power
In this way, we can directly import the entiremath_utils
, without writing.basic
or.advanced
Come on:
import math_utils print(math_utils.add(2, 3)) # Output 5print(math_utils.power(2, 3)) # Suppose there is a power function in advanced
It's equivalent to saying,__init__.py
letThe package becomes like a large moduleSimilarly, the external one does not need to know the module structure inside, just use it directly.
Example 2: Package Initialization Operation
__init__.py
You can also perform some initialization operations when the package is imported, such as loading configuration, setting logs, etc.:
# math_utils/__init__.py print("The math toolkit loaded successfully!") # As long as the import package is imported, this line of code will be executed
__init__.py What else can I do
In the Python project of a large manufacturer,__init__.py
It is also often used to do these things:
1. Dynamically import submodules
In large Python projects, manual maintenance is maintained as more and more modules are added__init__.py
It will become particularly complex and prone to errors. At this time, dynamic import of submodules becomes a hot topic.
Suppose we don't knowmath_utils
What modules are there in__init__.py
Dynamically scan and load on import:
# math_utils/__init__.py import os import importlib # Get the path to the current packagepackage_path = (__file__) # Iterate through all .py files in the current directory (excluding __init__.py itself)for module in (package_path): if (".py") and module != "__init__.py": module_name = module[:-3] # Remove the .py suffix importlib.import_module(f"{__name__}.{module_name}") # Dynamic import module
Effect:That way, when you write somewhere elseimport mypackage
,allmypackage
Inside.py
The files will be loaded automatically, no need to manuallyimport
Now!
If you don't add dynamic import, you need to write this:
import math_utils.basic print(math_utils.(1,2)) #If you directly import math_utils, an error will be reported: module 'math_utils' has no attribute 'basic'
Added dynamic import and can be written like this:
import math_utils print(math_utils.(1,2))
2. Modules that control external exposure
Sometimes, we don't want toallSubmodules are automatically imported, but only part of them is exposed for external use. You can use it at this time__all__
ComeManual controlAllowed to befrom mypackage import *
Accessed module.
# math_utils/__init__.py import os import importlib package_path = (__file__) __all__ = [] for module in (package_path): if (".py") and module != "__init__.py": module_name = module[:-3] __all__.append(module_name) # Modules exposed only in __all__ importlib.import_module(f"{__name__}.{module_name}")
Effect:
from math_utils import * print(basic) # Only modules in __all__ can be imported
3. Lazy Import
If some modules are larger and loading them will affect performance, you can useLazy loading(lazy import) technology, imported when needed, not inimport mypackage
All loads at once.
# math_utils/__init__.py import importlib def lazy_import(name): return importlib.import_module(f"{__name__}.{name}") module1 = lazy_import("basic")
Effect:
so,basic
It will only be imported when it is first used, improving performance!
4. Do version control
__init__.py
You can also add a version number to the package so that external code can access:
# math_utils/__init__.py __version__ = "1.0.0"
Then, you can use it elsewhere:
import math_utils print(math_utils.__version__) # Output "1.0.0"
5. Hide internal implementation
Some modules are "internal" and do not want to be accessed externally. What should I do? Can be__init__.py
Manual control inExposed content:
# math_utils/__init__.py from .basic import add, subtract __all__ = ["add", "subtract"] Things in # will not be directly imported
In this way, external use can onlymath_utils.add()
,butmath_utils.advanced
No direct access.
Ending
about__init__.py
, let’s stop talking about it! I hope this article can help you understand its function thoroughly and use it more confidently when writing Python projects in the future.
This is the article about this article about how to understand what __init__.py is in Python. This is all about this article. For more related Python __init__.py content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!