[英]How to reference to the top-level module in Python inside a package?
在下面的层次结构中,是否有一种方便且通用的方法来引用top_package,在下面的所有.py文件中使用通用术语? 我想有一个一致的方法来导入其他模块,所以即使“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
这应该做的工作:
top_package = __import__(__name__.split('.')[0])
这里的技巧是,对于每个模块, __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
运行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
无论容器目录的名称是什么,或者它位于何处,导入都将始终使用此安排。
但请注意,在您的原始示例中, top_package
可以轻松地充当容器目录本身。 所有你需要做的就是删除top_package/__init__.py
,你将完全保持相同的安排。
之前的import语句将更改为:
from level_one_b import my_lib
如果你愿意的话,你可以自由地重命名top_package
。
您可以使用__import__()
函数和包的__path__
属性的组合。
例如,假设您希望从包中的其他位置导入<whatever>.level_one_a.level_two.hello_world
。 你可以这样做:
import os
_temp = __import__(__path__[0].split(os.sep)[0] + ".level_one_a.level_two.hello_world")
my_hello_world = _temp.level_one_a.level_two.hello_world
此代码独立于顶级包的名称,可以在包中的任何位置使用。 这也很难看。
这适用于库模块:
import __main__ as main_package
TOP_PACKAGE = main_package.__package__.split('.')[0]
我相信如果不使用相对导入或命名包,#2是不可能的。 您必须通过显式调用其名称或使用相对导入来指定要导入的模块。 否则翻译会怎么知道你想要什么?
如果你将应用程序启动器放在top_level/
之上top_level/
并让它import top_leve
l,那么你可以从top_level包中的任何地方引用top_level.*
。
(我可以向您展示我正在开发的软件示例: http : //github.com/toddself/beerlog/ )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.