繁体   English   中英

如何在包里面引用Python中的顶级模块?

[英]How to reference to the top-level module in Python inside a package?

在下面的层次结构中,是否有一种方便且通用的方法来引用top_package,在下面的所有.py文件中使用通用术语? 我想有一个一致的方法来导入其他模块,所以即使“top_package”更改名称没有任何中断。

我不赞成使用像“..level_one_a”这样的相对导入,因为相对路径将与下面的每个python文件不同。 我正在寻找一种方式:

  1. 每个python文件可以对包中的同一模块使用相同的import语句。
  2. 在包中的任何.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM