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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:56:11  来源:igfitidea点击:

Is __init__.py not required for packages in Python 3.3+

pythonpython-3.xpackage

提问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,并bmodule.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()替代

Docs

文档

回答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。