如何引用包内Python中的顶级模块?

2024-04-25 08:44:17 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的层次结构中,是否有一种方便和通用的方法在下面的all.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
    

Tags: 模块文件方法py名称package层次结构init
3条回答

可以使用包的^{}函数和^{}属性的组合。

例如,假设您希望从包中的其他位置导入<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

此代码独立于顶级包的名称,可以在包中的任何位置使用。也很难看。

将包和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

这应该可以做到:

top_package = __import__(__name__.split('.')[0])

这里的技巧是,对于每个模块,__name__变量都包含到模块的完整路径,该路径由点分隔,例如,top_package.level_one_a.my_lib。因此,如果您想获得最上面的包名,只需要获得路径的第一个组件并使用__import__导入它。

尽管用于访问包的变量名仍然称为top_package,但您可以重命名包,如果仍然有效。

相关问题 更多 >