Python 3.3+中的包不需要__init__.py

时间:2016-05-10 13:19:39

标签: python python-3.x package

我正在使用Python 3.5.1。我在这里阅读了文档和包部分:https://docs.python.org/3/tutorial/modules.html#packages

现在,我有以下结构:

/home/wujek/Playground/a/b/module.py

module.py

class Foo:
    def __init__(self):
        print('initializing Foo')

现在,在/home/wujek/Playground

~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>

同样,现在在家中,Playground

的超级文件夹
~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>

实际上,我可以做各种各样的事情:

~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b

为什么这样做?我认为__init__.pya bmodule.py文件需要Playground个文件可以导入,当Python路径指向{{1}时文件夹?

这似乎已经从Python 2.7改变了:

~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module

__init__.py~/Playground/a都有~/Playground/a/b,效果很好。

5 个答案:

答案 0 :(得分:130)

Python 3.3+具有Implicit Namespace Packages,允许它创建没有__init__.py文件的包。

  

允许隐式命名空间包意味着提供__init__.py文件的要求可以完全删除,并受到影响......

使用__init__.py文件的旧方法仍然可以像在Python 2中那样工作。

答案 1 :(得分:74)

重要

@迈克的答案是正确的,但太不精确了。确实,Python 3.3+支持隐式命名空间包,允许它创建一个没有__init__.py文件的包。

但是,这仅适用于 EMPTY __init__.py 文件。因此,不再需要 EMPTY __init__.py 文件,可以省略。如果要在导入包或其任何模块或子包时运行特定的初始化脚本,则仍需要 __init__.py 文件。这是一个很棒的Stack Overflow answer,为什么你会想要使用__init__.py文件进行进一步的初始化,以防你想知道为什么这有用。

目录结构示例:

  parent_package/
     __init__.py            <- EMPTY, NOT NECESSARY in Python 3.3+
     child_package/
          __init__.py       <- STILL REQUIRED if you want to run an initialization script
          child1.py
          child2.py
          child3.py

parent_package/child_package/__init__.py

print("from parent")

<强>实施例

以下示例演示了在导入child_package或其中一个模块时如何执行初始化脚本。

示例1

from parent_package import child_package  # prints "from parent"

示例2

from parent_package.child_package import child1  # prints "from parent"

答案 2 :(得分:1)

根据我的经验,即使使用python 3.3+,有时还是需要一个空的__init__.py。一种情况是要将子文件夹称为包。例如,当我运行python -m test.foo时,直到我在测试文件夹下创建一个空的__init__.py时,它才起作用。我在这里谈论的是3.6.6版本,这是最近的版本。

除此之外,即使出于与现有源代码或项目准则兼容的原因,也很高兴在您的程序包文件夹中有一个空__init__.py

答案 3 :(得分:0)

我要说的是,只有在有人想要拥有implicit namespace package的情况下,才应该省略__init__.py。如果您不知道这意味着什么,那么您可能不想要它,因此即使在Python 3中,也应该继续使用__init__.py

答案 4 :(得分:0)

如果您有setup.py并且使用find_packages(),则必须在每个目录中都有__init__.py,以便自动找到软件包

  

只有包含__init__.py文件的软件包才能被识别

Docs