__init__.py在Python源目录中用于什么?
当前回答
__init__.py将其所在的目录视为可加载模块。
对于喜欢阅读代码的人,我将二位炼金术士的评论放在这里。
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
其他回答
它曾经是包的必需部分(旧的3.3之前的“常规包”,而不是更新的3.3+“命名空间包”)。
这是文档。
Python定义了两种类型的包,常规包和命名空间包。常规包是Python 3.2和更早版本中存在的传统包。常规包通常实现为包含__init__.py文件的目录。导入常规包时,将隐式执行__init__.py文件,它定义的对象将绑定到包的命名空间中的名称。__init__.py文件可以包含任何其他模块都可以包含的Python代码,并且Python将在导入模块时向模块添加一些附加属性。
但只需单击链接,它包含一个示例、更多信息和对命名空间包的解释,这是一种没有__init__.py的包。
名为__init__.py的文件用于将磁盘上的目录标记为Python包目录。如果你有文件
mydir/spam/__init__.py
mydir/spam/module.py
mydir在您的路径上,您可以将module.py中的代码导入为
import spam.module
or
from spam import module
如果删除__init__.py文件,Python将不再在该目录中查找子模块,因此导入模块的尝试将失败。
__init__.py文件通常为空,但可用于以更方便的名称导出包的选定部分,保存方便函数等。给定上面的示例,init模块的内容可以访问为
import spam
基于此
__init__.py将其所在的目录视为可加载模块。
对于喜欢阅读代码的人,我将二位炼金术士的评论放在这里。
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
__init__.py有两个主要原因
为了方便:其他用户不需要知道您的函数在包层次结构(文档)中的确切位置。您的程序包(_P)/__初始__.py文件1.py文件2.py...文件N.py#在__init__.py中从.file1导入*从.file2导入*...从.fileN导入*#在file1.py中def add():通过然后其他人可以调用add()从您的_package导入添加不知道file1的内部函数,例如从您的_package.file1导入添加如果你想初始化一些东西;例如,日志记录(应该放在顶层):导入logging.configlogging.config.dictConfig(Your_logging_config)
除了将目录标记为Python包并定义__all__之外,__init__.py还允许您在包级别定义任何变量。如果包以类似API的方式定义了将频繁导入的内容,那么这样做通常很方便。这种模式促进了对Pythonic“扁平优于嵌套”哲学的坚持。
一个例子
这里是我的一个项目中的一个示例,其中我经常导入一个名为Session的sessionmaker来与我的数据库交互。我编写了一个包含几个模块的“数据库”包:
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)
因为我在这里定义了会话,所以可以使用下面的语法启动新会话。该代码将与从“数据库”包目录内部或外部执行的代码相同。
from database import Session
session = Session()
当然,这只是一个小小的方便——另一种选择是在数据库包中的一个新文件(如“create_Session.py”)中定义Session,然后使用以下命令启动新会话:
from database.create_session import Session
session = Session()
进一步阅读
这里有一个非常有趣的reddit线程,介绍了__init__.py的适当用法:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
大多数人认为__init__.py文件应该非常薄,以避免违反“显式优于隐式”的原则。