假设您正在创建一个包含四个子包的 python 包,并且其中generic_stuff.py两个子包恰好需要一个模块。具体来说,可能generic_stuff.py包含一些用于读取和写入数据库的自定义函数,子包 1 和 2 包含要单独部署的 Web 服务器的代码。
问题是:
使子包 1 和 2 可用的正确方法是什么?
generic_stuff.py
我可以想到三种方法来做到这一点,但所有这些方法都感觉像是黑客:
generic_stuff.py自己的包的一部分并安装它。这是不能令人满意的,因为它污染了整个系统的命名空间(更不用说子包3和4了)。generic_stuff.py四个子包)添加到系统路径。这是不令人满意的,因为它将父目录中的所有内容添加到子包 1 和 2 的命名空间中。这可以通过放入来generic_stuff.py避免其自己的目录并将其添加到系统路径中,但即使如此,如果子包 1 和 2 中的多个模块正在使用多个通用模块(想象一下尝试重构该项目),这种方法也无法很好地扩展。generic_stuff.py:一份位于子包 1 中,一份位于子包 2 中。我需要解释为什么这是一个坏主意吗?我想我想到的是某种配置,也许会进入父目录__init__.py或其他东西,这将使模块 X 可用于子包 Y。是否存在类似的东西?
也许我是个什么东西,但看来你想得太多了。只需将generic_stuff.py其放在包的最高级别并在 sub1 和 sub2 中导入即可。您可以使用绝对或相对导入,没有名称污染,也不会弄乱 sys.path。例如:
封装结构:
package
|-- generic_stuff.py
|-- __init__.py
|-- sub1
| |-- __init__.py
| `-- sub1_module.py
|-- sub2
| `-- __init__.py
|-- sub3
| `-- __init__.py
`-- sub4
`-- __init__.py
Run Code Online (Sandbox Code Playgroud)
在所有需要 generic_stuff 的模块中执行如下操作:
# sub1_module.py
# import using a relative reference
import ..generic_stuff as gs
gs.some_tool()
# or an absolute reference
from package import generic_stuff as gs
gs.some_tool()
Run Code Online (Sandbox Code Playgroud)