Python中__init__.py文件的作用
Python中__init__.py文件的作用
技术背景
在Python中,__init__.py
文件曾经是Python包(在Python 3.3之前的“常规包”)的必要组成部分。Python定义了两种类型的包:常规包和命名空间包。常规包通常是一个包含 __init__.py
文件的目录,当导入该包时,__init__.py
文件会被隐式执行,其定义的对象会绑定到包的命名空间中。而从Python 3.3开始,引入了隐式命名空间包(PEP 420),不再要求使用 __init__.py
文件来定义可导入的Python包。
实现步骤
标记目录为Python包
如果目录结构如下:
1 |
|
当 mydir
在Python的搜索路径中时,可以使用以下方式导入 module.py
中的代码:
1 |
|
或者
1 |
|
若移除 __init__.py
文件,Python将不再将该目录视为包,尝试导入模块将会失败。
包级变量定义与便捷导入
在包中频繁使用的对象可以在 __init__.py
中定义,方便其他模块导入。例如,有如下包结构:
1 |
|
在 __init__.py
中定义数据库会话:
1 |
|
在其他模块中可以直接导入 Session
:
1 |
|
使用 __all__
控制导入
__init__.py
中的 __all__
变量可以控制使用 from package import *
时导入的子模块。例如,在 subPackage_b
的 __init__.py
中:
1 |
|
当执行 from package_x.subPackage_b import *
时,只有 module_n2
和 module_n3
会被导入。
核心代码
定义包级变量
1 |
|
使用 __all__
控制导入
1 |
|
包初始化代码
1 |
|
最佳实践
- 保持
__init__.py
简洁:遵循“显式优于隐式”的原则,避免在__init__.py
中写入过多复杂代码。 - 使用
__all__
控制导入:当需要控制from package import *
的行为时,使用__all__
变量明确指定要导入的子模块。 - 定义常用对象:将频繁使用的对象定义在
__init__.py
中,方便其他模块导入。
常见问题
Python 3.3之后是否还需要 __init__.py
从Python 3.3开始,__init__.py
不再是定义可导入Python包的必需文件,但为了明确指示该目录是一个包,建议仍然包含它,即使它是空的。
如何在Python 2中加载同级文件
在Python 2中,如果要加载同级文件,可以将当前文件的父目录添加到系统路径中:
1 |
|
不过,建议尽量使用 __init__.py
文件来管理包。