python 为什么在import_module()中添加一个点可以避免ImportError?

pod7payv  于 2022-12-28  发布在  Python
关注(0)|答案(1)|浏览(201)

具有以下目录树:

    • 注**:以下行为在使用/不使用__init__.py文件时相同。
top_package
|   top_module.py
|
+---package1
|   |   module1.py
|   |   __init__.py
|
\---package2
    |   module2.py
    |   __init__.py

使用top_module.py

from package1.module1 import CLASS1

a = CLASS1()

module1.py

from importlib import import_module

class CLASS1:

    def __init__(self):
        # this works:
        foo = getattr(
            import_module(name='..module2', package='package2.'), 'CLASS2')()
        
        # this raises ImportError.
        foo = getattr(
            import_module(name='..module2', package='package2'), 'CLASS2')()

其中唯一的区别是第一个在定义包参数时使用点(package='package2.'),而另一个不使用点(package='package2')。
module2.py

class CLASS2:

    def __init__(self):
        print(f'hi from: {__name__}')

我很难理解为什么在module1.py中,foo的第一个赋值语句有效,而下一个赋值语句无效,引发ImportError: attempted relative import beyond top-level package
top_module.py的目录运行top_module.py时发生此错误:

cd <path-to-top_package>/top_package
python top_module.py

文件中的相关信息指出
x1米10英寸1x
导入模块。* name * 参数以绝对或相对术语指定要导入的模块(例如pkg.mod..mod)。如果以相对术语指定名称,则必须将 * package * 参数设置为要用作解析包名称的定位点的包的名称(例如import_module('..mod', 'pkg.subpkg')将导入pkg.mod)。
这可能已经回答了我的问题,但我没有正确理解。

cpjpxq1n

cpjpxq1n1#

我错误地使用了import_module,主要原因是如果name指定了一个 * relative * 模块,那么它是相对于参数package的。
我错误地认为name相对于调用import_module的模块的__file__值(在本例中为module1.py)。
因此,第一版:

import_module(name='..module2', package='package2.')

导入package2.module2,因为..module2指定模块位于package参数的父级中。package2.的父级为package2
但是,

import_module(name='..module2', package='package2')

尝试从未知的package2父项导入,导致ImportError

相关问题