我的问题是关于编写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
问题
这是定义命名空间的好方法吗?或者有没有更好/通用的方法来组织 python 包的文件系统。(我没有找到合适的教程/示例。
在文件
package/subpackage/__init__.py
中,为什么它必须是:from package.subpackage.bar import bar
而不是:
from subpackage.bar import bar
?
这将导致错误:
Traceback (most recent call last):
File "script.py", line x, in <module>
import package.subpackage
File "..packagesubpackage__init__.py", line x, in <module>
from subpackage.bar import bar
ImportError: No module named 'subpackage'
这是定义命名空间的好方法吗?或者有没有更好/通用的方法来组织 python 包的文件系统。(我没有找到合适的教程/示例。
这是设置 Python 包的好方法。只有好而不是">好",因为foo.py
和bar.py
的内容.
我不喜欢使用
package.foo.foo()
/package.subpackage.bar.bar()
,想使用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 *
但也不被认为是好的。
或者,foo
和bar
包应该包含更多,如foo.function1
、foo.other_func
、bar.drink
等,这给了它更人性化的可理解的组织。
示例和参考不在好的 StackOverflow 问题范围内,但这里有一些,对于一个经过深思熟虑的问题:
- 构建你的项目 — Python的顺风车指南
- 组织模块和包的 Python 方式
- 如何组织一个Python项目?
第二个问题的答案:
在文件
package/subpackage/__init__.py
中,为什么它必须是:
from package.subpackage.bar import bar
而不是:
from subpackage.bar import bar
?
是你必须使用from .bar import bar
.当您要在包结构内执行相对导入时,将使用点。请参阅:https://docs.python.org/3/tutorial/modules.html#intra-package-references