问题:Python 3.3+中的软件包不需要__init__.py吗
我正在使用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__.py
两者都需要文件(空文件可以工作),a
并且b
要module.py
在Python路径指向Playground
文件夹时可导入?
这似乎与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
它工作正常。
回答 0
Python 3.3+具有隐式命名空间包,允许它创建不带__init__.py
文件的包。
允许隐式命名空间包意味着可以完全放弃提供
__init__.py
文件的要求,并使其受到影响。
__init__.py
文件的旧方法仍然可以在Python 2中使用。
回答 1
重要
@Mike的回答是正确的,但过于精确。确实,Python 3.3+支持隐式命名空间包,这允许它创建不带__init__.py
文件的包。
但是,这仅适用于__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
如果你有 setup.py
在项目中并在其中使用find_packages()
,则必须__init__.py
在每个目录中都有一个文件,以便自动找到软件包。
程序包仅在包含
__init__.py
文件的情况下才被识别
UPD:如果你想使用隐式命名空间包,而__init__.py
你只需要使用find_namespace_packages()
替代
回答 3
我要说的是,__init__.py
只有一个人想要拥有隐式命名空间包时,才应该省略它。如果您不知道这意味着什么,则可能不想要它,因此您应该__init__.py
在Python 3中继续使用even。