hll*_*lau 19 python module packages
在下面的层次结构中,是否有一种方便且通用的方法可以在下面的所有.py文件中使用通用术语来引用top_package?我想有一个一致的方法来导入其他模块,所以即使"top_package"更改名称没有任何中断.
我不赞成使用像"..level_one_a"这样的相对导入,因为相对路径将与下面的每个python文件不同.我正在寻找一种方式:
在包中的任何.py文件中对"top_package"的解耦引用,因此无论名称"top_package"如何变化,都没有中断.
top_package/
__init__.py
level_one_a/
__init__.py
my_lib.py
level_two/
__init__.py
hello_world.py
level_one_b/
__init__.py
my_lib.py
main.py
Run Code Online (Sandbox Code Playgroud)jco*_*ado 13
这应该做的工作:
top_package = __import__(__name__.split('.')[0])
Run Code Online (Sandbox Code Playgroud)
这里的技巧是,对于每个模块,__name__变量包含由点分隔的模块的完整路径,例如,top_package.level_one_a.my_lib.因此,如果要获取顶级包名称,只需获取路径的第一个组件并使用它进行导入即可__import__.
尽管仍然调用用于访问包的变量名称top_package,但您可以重命名包,如果仍然可以.
将您的包和main脚本放入外部容器目录中,如下所示:
container/
main.py
top_package/
__init__.py
level_one_a/
__init__.py
my_lib.py
level_two/
__init__.py
hello_world.py
level_one_b/
__init__.py
my_lib.py
Run Code Online (Sandbox Code Playgroud)
当main.py运行时,它的父目录(container)将被自动添加到开始sys.path.由于top_package现在位于同一目录中,因此可以从包树中的任何位置导入它.
所以hello_world.py可以level_one_b/my_lib.py像这样导入:
from top_package.level_one_b import my_lib
Run Code Online (Sandbox Code Playgroud)
无论容器目录的名称是什么,或者它位于何处,导入都将始终使用此安排.
但请注意,在您的原始示例中,top_package它可以轻松地充当容器目录本身.所有你需要做的就是删除top_package/__init__.py,你将有效地保持相同的安排.
之前的import语句将更改为:
from level_one_b import my_lib
Run Code Online (Sandbox Code Playgroud)
如果你愿意,你可以自由重命名top_package.