概述
在 Python 中,__init__.py
文件的作用是将一个目录标记为 Python 模块(在 Python 3.3 之后,即使没有 __init__.py
文件,目录也可以作为模块,但显式定义 __init__.py
更加清晰和规范)。
当你导入一个包或模块时,__init__.py
会自动执行,且其内容会暴露给该模块的命名空间。
对于一个python项目,里面的每一个文件夹都可以认为是一个package,而每一个.py文件被认为是一个module。如果你用的IDE是PyCharm,那么当你新建一个Python Package的时候,PyCharm都会自动为你新建一个__init__.py文件。这个__init__.py文件可以看作这个package的初始化文件。
项目结构
"""
.
├── demo.py
├── package
| ├── __init__.py
| ├── module.py
"""
__init__.py文件效果
demo.py
# demo.py
import package
__init__.py:
# __init__.py
print("__init.py file is called!")
如果执行 demo.py文件,输出结果如下,说明__init__.py文件都被执行了。
$ python demo.py
__init.py file is called!
把demo.py中的import package 换成 import package.module 也是一样的结果。
因为:当你导入
package.module
时,Python 会先加载package
这个包,而加载包的过程会执行package/__init__.py
中的代码。之后,Python 会加载package/module.py
中的内容。如果是import package,那么 Python 只会加载并执行
package/__init__.py
中的内容,而不会执行package/module.py
,因为你没有显式导入module
。
__init__.py文件作用
1. 简化import语法
可以直接在__imit__.py文件中导入所需要的包或者模块,然后在执行文件中直接from package import 模块就好了,不需要单独从每一个文件中import 模块。
举例:
# module.py
def a_function():
print("Test function is called!")
如果我想在demo.py中调用a_function函数,直接调用:
# demo.py
from package.module import a_function
a_function()
在__init__.py文件中调用后,在demo.py中使用:
# __init__.py
from package.module import a_function
# demo.py
from package import a_function
a_function()
2. 批量导入
如果在module.py文件中定义了多个函数:
# module.py
def a_function_1():
print("Test function 1 is called!")
def a_function_2():
print("Test function 2 is called!")
想在demo.py中调用,可以在__init__.py文件中批量导入:
# __init__.py
from package.module import *
再在demo.py中批量导入:
# demo.py
from package import *
a_function_1()
如果只允许function_1被外界调用,就可以在__init__.py文件中修改:
# __init__.py
from package.module import a_function_1
这样在demo.py文件中,调用其他函数如function_2就会报错。
3. __all__的应用
调用__all__属性,在__init__.py中定义可以被外界调用的类和方法:
# __init__.py
__all__ = ['a_function_1'] # 这样,在demo.py只能调用a_function_1方法
from package.module import *