【问题标题】:Why can't Main Module see sub-module inside it?为什么主模块看不到里面的子模块?
【发布时间】:2021-05-17 06:37:11
【问题描述】:

我正在编辑以最小化为可重现的示例:

cal.py 的内容

import M1

M1.SM1.nice_hello.hello()

目录结构:

M1/
├── __init__.py
└── SM1
    ├── __init__.py
    └── nice_hello.py

SM1/nice_hello.py 的内容:

def hello():
    print(f'Hello my friend!!!')

所有其他文件(init.py 文件)为空。

运行 cal.py:

export PYTHONPATH=/PATH/TO/M1 ; python cal.py

但这给了我以下错误:

Traceback (most recent call last):
  File "cal.py", line 3, in <module>
    M1.SM1.nice_hello.hello()
AttributeError: module 'M1' has no attribute 'SM1'

【问题讨论】:

  • cal.py和M1是同级的吗?
  • 你是如何运行cal.py的?从命令行?从哪个目录?
  • 我愿意 export PYTHONPATH=/PATH/TO/M1 ;我使用python cal.py 运行
  • 你的目录结构中的 cal.py 在哪里?
  • 我相信stackoverflow.com/a/8899345 和section 6.4 from the Python docs 一起回答了您的问题。它还有助于检查 sys.modules 以找出已加载的模块,并使用 dir() 查看它们定义的名称。

标签: python import importerror nameerror


【解决方案1】:

如果您导入整个模块名称,它应该可以工作,即在文件cal.py中

import M1.SM1.nice_hello

M1.SM1.nice_hello.hello()

【讨论】:

  • 但是为什么M1在里面的时候不能使用SM1呢?
  • 子模块不会自动导入,但您可以通过在各自的__init__.py-files 中执行一系列导入来生成此行为。
  • 在我导入 MainModule 时有什么方法可以导入子模块。
  • 在这个例子中,当你在M1.__init__.py中包含import M1.SM1.nice_hello这一行时,你可以在主模块中导入M1,然后调用M1.SM1.nice_hello.hello()。或者,您可以在M1/__init__.py 中添加import M1.SM1,在SM1.__init__.py 中添加import M1.SM1.nice_hello。
【解决方案2】:

子模块不会以递归方式导入,如果您希望这样做,您可以执行以下操作:-

A) 在 M1 模块中创建 init.py 文件(我想你已经有了)

B) 在您的 init.py 文件中包含以下代码:-

import importlib
import pkgutil

def import_submodules(package, recursive=True):
""" Import all submodules of a module, recursively, including subpackages

:param package: package (name or actual module)
:type package: str | module
:rtype: dict[str, types.ModuleType]
"""
if isinstance(package, str):
    package = importlib.import_module(package)
results = {}
for loader, name, is_pkg in pkgutil.walk_packages(package.__path__):
    full_name = package.__name__ + '.' + name
    results[full_name] = importlib.import_module(full_name)
    if recursive and is_pkg:
        results.update(import_submodules(full_name))
return results

这将帮助您导入该包 (M1) 中的所有子模块

现在在您的 cal.py 中执行以下操作:-

import M1
M1.import_submodules(M1)
def hello():
    print(f'Hello my friend!!!')

希望这能解决您的问题,并可能指导您如何在 python 中递归地导入模块

参考:- How to import all submodules?

如果需要进一步说明,请在 cmets 中与我们联系。很乐意提供帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 2022-07-06
    • 2021-05-22
    • 2021-01-31
    • 2015-08-13
    • 2018-07-09
    • 2021-11-15
    相关资源
    最近更新 更多