问题
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 namedspam.py
in a list of directories given by the variablesys.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 variablePATH
).- 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