我正在使用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
文件需要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
,效果很好。
答案 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)