ModuleNotFoundError when using importlib.import_module

那年仲夏 提交于 2020-03-03 05:03:27

问题


I have the following folder structure and I have a test method in util.py. When the util method is run, I see an error with a module that is imported within the module where I am trying to get all classes.

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

When I run my test method from util, I get the following error:

ModuleNotFoundError: No module named AReport

回答1:


Assuming you did not change anything with sys.path or with PYTHONPATH, the problem is that AReport module is not "visible" from util.py.

You can check this by adding this at the top of util.py:

import sys
print(sys.path)

That's going to print out a list of all paths where the interpreter will look for modules. You'll see that only the path to the Parent module is there, because this is where the util.py was run from. This is explained in The Module Search Path documentation:

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.

When you do

from AReport import AReport

it will look for a AReport module from the Parent directory, but it's not there because only the report package is directly under the /path/to/Parent directory, which is why Python raises the ModuleNotFoundError. If you do instead

from report.AReport import AReport

it's going to work because the report package is under /path/to/Parent.

If you want to avoid the report. prefix when importing, one option is to add the report package to the sys.path on util.py:

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

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

Then your from AReport import will now work. Another option is to add /path/to/Parent/report to your PYTHONPATH environment variable before running util.py.

export PYTHONPATH=$PYTHONPATH:/path/to/Parent/report

I usually go with the PYTHONPATH option for tests, so that I don't need to modify the code.




回答2:


try:

from report.AReport import AReport


来源:https://stackoverflow.com/questions/56603077/modulenotfounderror-when-using-importlib-import-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!