如何在(子)模块中使用 __init__.py 来定义命名空间?

How to use __init__.py in (sub-)modules to define namespaces?

我的问题是关于编写 Python (3.x) 包和(子)模块以及正确使用 __init__.py 文件来声明命名空间。
我以前用 C++ 编写代码,所以我喜欢使用很多单独的文件来组织项目。例如,(imo) 如果一个模块包含多个 类,每个都应该在一个单独的文件中。

由于我在Python开发经验不足,所以很难用一个简单的问题来表达我的想法。 因此,让我们以下面的小 python 包为例。

目录布局

dir
 |
 +-- example
 |    |
 |    +-- script.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- foo.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- bar.py

让我们看看文件。

文件内容

package/foo.py:

def foo:
    print('foo')

package/subpackage/bar.py:

def bar:
    print('bar')

以下 example/script.py 工作正常。

import sys
sys.path.insert(0, '..')

import package
import package.subpackage


package.foo.foo()
package.subpackage.bar.bar()

我不喜欢使用 package.foo.foo() / package.subpackage.bar.bar() 而想使用 package.foo() / package.subpackage.bar().

而且我不想使用 from package.subpackage.bar import bar,因为我不想将子包的命名空间混合到脚本中。

解决方案

我使用 __init__.py 文件来实现。

package/__init__.py:

from package.foo import foo

package/subpackage/__init__.py:

from package.subpackage.bar import bar

问题

这将导致错误:

Traceback (most recent call last):
File "script.py", line x, in <module>
import package.subpackage
File "..\package\subpackage\__init__.py", line x, in <module>
from subpackage.bar import bar
ImportError: No module named 'subpackage'

Is this a good python-like way to define namespaces? Or is there a better / common way to organize the file-system of a package in python. (I did not find a proper tutorial/example for this.)

这是设置 Python 程序包的 好的 方法。只有 可以 而不是 'good' 因为 foo.pybar.py.

的内容

I don't like to use package.foo.foo() / package.subpackage.bar.bar() and would like to use package.foo() / package.subpackage.bar().

在这种情况下,你不能。不混合名称空间是不做 from package.subpackage.bar import bar.

的充分理由

如果def foo(): ...def bar(): ...直接在__init__.py就更好了。这样,您就可以完成 package.foo()package.subpackage.bar()。它也可以通过在 init 中使用 __all__ 来完成,但是 import * 也被认为是不好的。

或者,foobar 包中应该包含更多内容,例如 foo.function1foo.other_funcbar.drink 等。更多 human-friendly 易于理解的组织。

示例和参考资料不在 Whosebug 好的问题范围内,但这里有一些很好的 thought-out 问题:

第二题答案:

In file package/subpackage/__init__.py, why does it have to be:

from package.subpackage.bar import bar

and not:

from subpackage.bar import bar?

就是你要用from .bar import bar。当您想在包结构中进行相对导入时使用点。参见:https://docs.python.org/3/tutorial/modules.html#intra-package-references