gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 02:40:41 25 4
gpt4 key购买 nike

我的问题是关于编写 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

包/子包/__init__.py:

from package.subpackage.bar import bar

问题

  • 这是一种类似于 python 的定义命名空间的好方法吗?或者是否有更好/通用的方法来组织 python 中包的文件系统。 (我没有为此找到合适的教程/示例。)

  • 在文件 package/subpackage/__init__.py 中,为什么它必须是:

    从 package.subpackage.bar 导入栏

    而不是:

    从 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 包的好的方法。由于 foo.pybar.py 的内容,只有 ok 而不是“good”。

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

在这种情况下,你不能。不混合 namespace 是不执行 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 等,使其组织起来更加人性化、易于理解。

示例和引用不在好的 StackOverflow 问题的范围内,但这里有一些,对于一个深思熟虑的问题:

关于python - 如何在(子)模块中使用 __init__.py 来定义命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41871239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com