Python 定义了两种类型的包,常规包( regular packages)和命名空间包(namespace packages)。
常规包是 Python 3.2 及更早版本中存在的传统包。常规包通常实现为包含__init__.py
文件的目录。
当一个常规包被导入时,这个init.py文件被隐式执行,它定义的对象被绑定到包命名空间中的名字。该init.py文件可以包含任何其他模块可以包含的相同 Python 代码,并且 Python 会在导入模块时为其添加一些附加属性。
__init__.py
文件 用于将磁盘上的目录标记为 Python 包目录。
如果你有下面的文件
mydir/test/__init__.py
mydir/test/module.py
Code language: JavaScript (javascript)
并且mydir在你的系统路径里,你可以将module.py代码导入为
import test.module
Code language: JavaScript (javascript)
或者
from test import module
Code language: JavaScript (javascript)
如果你删除该__init__.py
文件,Python 将不再在该目录中查找子模块,因此尝试导入该模块将失败。
_init__.py
文件通常是空的,但可用于以更方便的名称导出包的选定部分,保存方便的函数等。
注意:init.py在 Python 2.X 下是必需的,在 Python 2.7.12 下仍然需要,但从(据称)Python 3.3 开始不再需要它
init.py还允许在包级别定义任何变量。
如果包以类似 API 的方式定义了将频繁导入的内容,那么这样做通常很方便。这种模式促进了对 Pythonic“扁平优于嵌套”哲学的坚持。
这是我的一个项目中的一个示例,其中我经常导入一个sessionmaker调用Session来与我的数据库进行交互。我写了一个包含几个模块的database
包:
database/
__init__.py
schema.py
insertions.py
queries.py
其中__init__.py
包含以下代码:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Code language: JavaScript (javascript)
由于Session
在这里定义,可以使用下面的代码开始一个新会话。
from database import Session
session = Session()
Code language: JavaScript (javascript)