使用 importlib.import_module 时出现 ModuleNotFoundError

ModuleNotFoundError when using importlib.import_module

我有以下文件夹结构,我在util.py中有一个测试方法。当 util 方法是 运行 时,我发现在我试图获取所有 类.

的模块中导入的模块出错
Parent
--report <dir>
----__init__.py
----AReport.py
----names_list.py
--util.py

util.py

import inspect
import importlib
import importlib.util

def get_class_names(fileName):
    for name, cls in inspect.getmembers(importlib.import_module(fileName, package='report'), inspect.isclass):
        print(name, cls)

if __name__ == '__main__':
    get_class_names('report.names_list')

names_list.py

from AReport import AReport

class Team:
    name = ""
    def __init__(self, name):
        self.name = name

class Names_List(AReport):
    def __init__(self, name=None):
        AReport.__init__(self, name)

    def test(self):
        print('In test')        

AReport.py

from abc import ABCMeta, abstractmethod

class AReport(metaclass=ABCMeta):
    def __init__(self, name=None):
        if name:
            self.name = name

    def test(self):
        pass

当我从 util 运行 我的测试方法时,我得到以下错误:

ModuleNotFoundError: No module named AReport

尝试:

from report.AReport import AReport

假设您没有使用 sys.pathPYTHONPATH 进行任何更改,问题是 AReport 模块在 util.py.[=42 中不“可见” =]

您可以通过在 util.py 的顶部添加以下内容来检查:

import sys
print(sys.path)

这将打印出解释器将在其中查找模块的所有路径的列表。您会看到只有 Parent 模块的路径在那里,因为这是 util.py 来自 运行 的地方。 The Module Search Path 文档对此进行了解释:

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • The directory containing the input script (or the current directory when no file is specified).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • The installation-dependent default.

当你从父目录运行 util.py(=“包含输入脚本的目录”),你做

from AReport import AReport

它会从父目录中寻找一个 AReport 模块,但它不在那里,因为只有 report 包直接在 /path/to/Parent 目录下。这就是 Python 提出 ModuleNotFoundError 的原因。如果你这样做

from report.AReport import AReport

它将起作用,因为 report 包在 /path/to/Parent.

如果要在导入时避免使用 report. 前缀,一种选择是将 report 包添加到 util.py 上的 sys.path:

import sys
sys.path.append("./report")

print(sys.path)
# should now show the /path/to/Parent/report on the list

那么您的 from AReport 导入现在可以工作了。另一种选择是在 运行ning util.py.

之前将 /path/to/Parent/report 添加到您的 PYTHONPATH 环境变量
export PYTHONPATH=$PYTHONPATH:/path/to/Parent/report

我通常使用 PYTHONPATH 选项进行测试,这样我就不需要修改代码。