Python 3.3+ 中的包不需要 __init__.py
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37139786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is __init__.py not required for packages in Python 3.3+
提问by wujek
I am using Python 3.5.1. I read the document and the package section here: https://docs.python.org/3/tutorial/modules.html#packages
我正在使用 Python 3.5.1。我在这里阅读了文档和包部分:https: //docs.python.org/3/tutorial/modules.html#packages
Now, I have the following structure:
现在,我有以下结构:
/home/wujek/Playground/a/b/module.py
module.py:
module.py:
class Foo:
def __init__(self):
print('initializing Foo')
Now, while in /home/wujek/Playground:
现在,在/home/wujek/Playground:
~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>
Similarly, now in home, superfolder of Playground:
同样,现在在家里,超级文件夹Playground:
~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>
Actually, I can do all kinds of stuff:
其实,我可以做各种各样的事情:
~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b
Why does this work? I though there needed to be __init__.pyfiles (empty ones would work) in both aand bfor module.pyto be importable when the Python path points to the Playgroundfolder?
为什么这样做?我虽然有被需要的__init__.py文件(空的都可以)两种a,并b为module.py要导入的时候Python的路径指向Playground文件夹?
This seems to have changed from Python 2.7:
这似乎从 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
With __init__.pyin both ~/Playground/aand ~/Playground/a/bit works fine.
随着__init__.py在这两个~/Playground/a和~/Playground/a/b它工作正常。
采纳答案by Mike Müller
Python 3.3+ has Implicit Namespace Packagesthat allow it to create a packages without an __init__.pyfile.
Python 3.3+ 具有隐式命名空间包,允许它创建没有__init__.py文件的包。
Allowing implicit namespace packages means that the requirement to provide an
__init__.pyfile can be dropped completely, and affected ... .
允许隐式命名空间包意味着可以完全放弃提供
__init__.py文件的要求,并影响......。
The old way with __init__.pyfiles still works as in Python 2.
旧的__init__.py文件方式仍然像在 Python 2 中一样工作。
回答by AndreasLukas
IMPORTANT
重要的
@Mike's answer is correct but too imprecise. It is true that Python 3.3+ supports Implicit Namespace Packagesthat allows it to create a package without an __init__.pyfile.
@Mike 的答案是正确的,但太不精确了。Python 3.3+ 确实支持隐式命名空间包,允许它创建一个没有__init__.py文件的包。
This however, ONLY applies to EMPTY __init__.pyfiles. So EMPTY __init__.pyfiles are no longer necessary and can be omitted. If you want to run a particular initialization script when the package or any of its modules or sub-packages are imported, you still require an __init__.pyfile. This is a great Stack Overflow answerfor why you would want to use an __init__.pyfile to do some further initialization in case you wondering why this is in any way useful.
但是,这仅适用于EMPTY__init__.py文件。所以EMPTY__init__.py文件不再需要,可以省略。如果您想在导入包或其任何模块或子包时运行特定的初始化脚本,您仍然需要一个__init__.py文件。这是一个很棒的Stack Overflow 答案,可以说明为什么您想使用__init__.py文件进行一些进一步的初始化,以防您想知道为什么这有任何用处。
Directory Structure Example:
目录结构示例:
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:
parent_package/child_package/__init__.py:
print("from parent")
EXAMPLES
例子
The below examples demonstrate how the initialization script is executed when the child_packageor one of its modules is imported.
以下示例演示了在child_package导入其模块或其中一个模块时如何执行初始化脚本。
Example 1:
示例 1:
from parent_package import child_package # prints "from parent"
Example 2:
示例 2:
from parent_package.child_package import child1 # prints "from parent"
回答by techkuz
If you have setup.pyin your project and you use find_packages()within it, it is necessary to have an __init__.pyfile in every directory for packages to be automatically found.
如果您setup.py的项目中有并在其中使用find_packages(),则必须__init__.py在每个目录中都有一个文件,以便自动找到包。
Packages are only recognized if they include an
__init__.pyfile
只有包含
__init__.py文件的包才能被识别
UPD: If you want to use implicit namespace packages without __init__.pyyou just have to use find_namespace_packages()instead
UPD:如果你想使用隐式命名空间包,而__init__.py你只需要使用find_namespace_packages()替代
回答by Mi-La
I would say that one should omit the __init__.pyonly if one wants to have the implicit namespace package. If you don't know what it means, you probably don't want it and therefore you should continue to use the __init__.pyeven in Python 3.
我会说,__init__.py如果想要拥有隐式命名空间包,则应该省略only 。如果你不知道它是什么意思,你可能不想要它,因此你应该继续__init__.py在 Python 3 中使用even。

