我的问题是编写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的方式来定义命名空间吗?或者是否有更好/通用的方法来组织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 "..\package\subpackage\__init__.py", line x, in <module>
from subpackage.bar import bar
ImportError: No module named 'subpackage'
答案 0 :(得分:5)
这是一种类似python的方式来定义名称空间吗?或者是否有更好/通用的方法来组织python中的包的文件系统。 (我没有为此找到合适的教程/示例。)
这是设置Python包的 okay 方法。由于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问题的范围内,但这里有一些问题,这是一个深思熟虑的问题:
答案 1 :(得分:3)
第二个问题的答案:
在文件
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