什么是 __init__.py 在Python源目录中?

有帮助吗?

解决方案

它曾经是一个封装的必要部分(老,预-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

from spam import module

如果您删除的文件__init__.py,Python将不再寻找该目录内的子模块,所以尝试导入模块会失败。

__init__.py文件通常是空的,但可以用于导出下更方便名字包装的选定部分,保留便利功能等 给定上述示例中,init模块的内容可作为

来访问
import spam

基于

在除了标记的目录作为Python包并限定__all__,的 __init__.py允许定义在封装级的任何变量。这样做往往是方便的,如果一个包定义的东西,将被导入经常,在API般的时尚。这种模式促进坚持Python化“扁平比嵌套更好”的理念。

一个例子

下面是我的项目,我在其中频繁导入sessionmakerSession与我的数据库交互的一个例子。我写了“数据库”包与几个模块:

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)

由于我在这里定义Session,我可以使用下面的语法开始一个新会话。该代码将是从内部或外部“数据库”包目录的执行相同。

from database import Session
session = Session()

当然,这是一个小便利 - 的替代方案是在像在我的数据库包“create_session.py”的新的文件来定义Session,以及使用启动新的会话:

from database.create_session import Session
session = Session()

进一步阅读

这里有覆盖__init__.py的适当用途一个非常有趣的书签交易螺纹:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

在大多数人看来似乎是__init__.py文件应该是非常薄的,以避免违反“显胜于隐”的理念。

主要有2个原因 __init__.py

  1. 为了方便:其他用户不需要知道您的函数在包层次结构中的确切位置。

    your_package/
      __init__.py
      file1.py
      file2.py
        ...
      fileN.py
    
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    
    # in file1.py
    def add():
        pass
    

    然后其他人可以通过以下方式调用 add()

    from your_package import add
    

    不知道 file1,就像

    from your_package.file1 import add
    
  2. 如果你想要初始化一些东西;例如,日志记录(应放在顶层):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    

__init__.py文件使得它含有作为模块Python视目录。

此外,这是在一个模块中要加载的第一个文件,因此可以使用它来执行要每一个模块被加载时运行,或指定要导出的子模块的代码。

从Python 3.3开始, __init__.py 不再需要将目录定义为可导入的 Python 包。

查看 PEP 420:隐式命名空间包:

对不需要的包目录的本机支持 __init__.py 标记文件,并且可以自动跨越多个路径段(受到命名空间包的各种第三方方法的启发,如中所述 PEP 420)

这是测试:

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

参考:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Python 3 中的包不需要 __init__.py 吗?

在Python包的定义是非常简单的。 Java一样的层次结构和目录结构是相同的。但是,你必须有__init__.py在一个包。我将解释下面的例子中的文件__init__.py

package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py

__init__.py可以是空的,只要它的存在。这表明该目录应该被视为一个包。当然,__init__.py也可以设置适当的内容。

如果我们在module_n1增加一个功能:

def function_X():
    print "function_X in module_n1"
    return

运行后:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

然后,我们遵循层级包和称为module_n1功能。我们可以使用__init__.py在subPackage_b这样的:

__all__ = ['module_n2', 'module_n3']

运行后:

>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_n1

因此,使用*的进口,模块封装受到__init__.py内容。

虽然Python的工作没有一个__init__.py文件你还应该包括一个。

它指定一个包应被视为一个模块,所以因此包括它(即使它是空的)。

<强>还有,你可以实际使用__init__.py文件的情况下:

想象一下,你有以下文件结构:

main_methods 
    |- methods.py

methods.py包含在此:

def foo():
    return 'foo'

要使用foo()你需要下列之一:

from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()

也许有你需要(或希望)保持methods.pymain_methods(例如运行时间/依赖性),但你只想要导入main_methods


如果您改变methods.py的名称__init__.py,那么你可以通过只导入foo()使用main_methods

import main_methods
print(main_methods.foo()) # Prints 'foo'

此工作,因为__init__.py被作为包的一部分处理。


一些Python包真正做到这一点。一个例子是与 JSON ,其中运行import json实际上从__init__.py包导入json看到包文件结构这里):

  

<强>源代码: Lib/json/__init__.py

__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
>>> 

它便于导入其他蟒文件。当你放在这个文件在目录(说的东西)含有其他PY文件,那么你可以这样做进口stuff.other。

root\
    stuff\
         other.py

    morestuff\
         another.py

如果没有这个__init__.py目录里面的东西,你不能导入other.py,因为Python不知道在哪里的东西源代码,无法将其识别为一个包。

这是__init__.py文件使其进口容易。当__init__.py是一个包内时,功能a()可以从文件b.py被导入像这样:

from b import a

如果没有它,但是,你不能直接导入。你必须修改系统路径:

import sys
sys.path.insert(0, 'path/to/b.py')

from b import a
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top