[英]ModuleNotFoundError when using importlib.import_module
I have the following folder structure and I have a test method in util.py.我有以下文件夹结构,并且在 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.
运行 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名称列表.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:当我从 util 运行我的测试方法时,出现以下错误:
ModuleNotFoundError: No module named AReport
Assuming you did not change anything with sys.path
or with PYTHONPATH
, the problem is that AReport
module is not "visible" from util.py.假设您没有对
sys.path
或PYTHONPATH
任何更改,问题是AReport
模块在AReport
中不“可见”。
You can check this by adding this at the top of util.py
:您可以通过在
util.py
顶部添加以下内容来检查这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.您将看到只有
Parent
模块的路径在那里,因为这是util.py
运行位置。 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.当导入名为
spam
的模块时,解释器首先搜索具有该名称的内置模块。 If not found, it then searches for a file namedspam.py
in a list of directories given by the variablesys.path
.如果未找到,它将在变量
sys.path
给出的目录列表中搜索名为spam.py
的文件。sys.path
is initialized from these locations:sys.path
从这些位置初始化:
- 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
).PYTHONPATH
(目录名称列表,语法与 shell 变量PATH
)。- The installation-dependent default.
依赖于安装的默认值。
When you run util.py
from the Parent directory (= " The directory containing the input script "), and you do当您从父目录(=“包含输入脚本的目录”)运行
util.py
,您会
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.它会从 Parent 目录中寻找
AReport
模块,但它不存在,因为只有report
包直接在 /path/to/Parent 目录下。 That is why Python raises the ModuleNotFoundError
.这就是 Python 引发
ModuleNotFoundError
。 If you do instead如果你这样做
from report.AReport import AReport
it's going to work because the report
package is under /path/to/Parent.它会起作用,因为
report
包在 /path/to/Parent 下。
If you want to avoid the report.
如果你想避免
report.
prefix when importing, one option is to add the report
package to the sys.path
on util.py
:导入时添加前缀,一种选择是将
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
Then your from AReport
import will now work.然后你的
from AReport
导入现在可以工作了。 Another option is to add /path/to/Parent/report to your PYTHONPATH
environment variable before running util.py
.另一种选择是在运行
util.py
之前将 /path/to/Parent/report 添加到您的PYTHONPATH
环境变量中。
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.我通常使用
PYTHONPATH
选项进行测试,这样我就不需要修改代码。
尝试:
from report.AReport import AReport
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.