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__.py
files (empty ones would work) in both a
and b
for module.py
to be importable when the Python path points to the Playground
folder?
为什么这样做?我虽然有被需要的__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__.py
in both ~/Playground/a
and ~/Playground/a/b
it 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__.py
file.
Python 3.3+ 具有隐式命名空间包,允许它创建没有__init__.py
文件的包。
Allowing implicit namespace packages means that the requirement to provide an
__init__.py
file can be dropped completely, and affected ... .
允许隐式命名空间包意味着可以完全放弃提供
__init__.py
文件的要求,并影响......。
The old way with __init__.py
files 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__.py
file.
@Mike 的答案是正确的,但太不精确了。Python 3.3+ 确实支持隐式命名空间包,允许它创建一个没有__init__.py
文件的包。
This however, ONLY applies to EMPTY __init__.py
files. So EMPTY __init__.py
files 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__.py
file. This is a great Stack Overflow answerfor why you would want to use an __init__.py
file 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_package
or 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.py
in your project and you use find_packages()
within it, it is necessary to have an __init__.py
file in every directory for packages to be automatically found.
如果您setup.py
的项目中有并在其中使用find_packages()
,则必须__init__.py
在每个目录中都有一个文件,以便自动找到包。
Packages are only recognized if they include an
__init__.py
file
只有包含
__init__.py
文件的包才能被识别
UPD: If you want to use implicit namespace packages without __init__.py
you 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__.py
only 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__.py
even in Python 3.
我会说,__init__.py
如果想要拥有隐式命名空间包,则应该省略only 。如果你不知道它是什么意思,你可能不想要它,因此你应该继续__init__.py
在 Python 3 中使用even。