使用portlib.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
解决方案
假设您没有使用sys.path
或PYTHONPATH
更改任何内容,则问题是AReport
模块不是util.py中的可见模块。
您可以通过在util.py
的顶部添加以下内容进行检查:
import sys
print(sys.path)
这将打印出解释器查找模块的所有路径的列表。您将看到那里只有Parent
模块的路径,因为这是util.py
运行的位置。这在The Module Search Path文档中进行了解释:
导入名为spam
的模块时,解释器首先搜索 用于具有该名称的内置模块。如果未找到,则它将搜索 提供的目录列表中名为spam.py
的文件 变量sys.path
。sys.path
从以下位置初始化:
- 包含输入脚本的目录(或当前目录 未指定文件时)。
(目录名的列表,语法与 外壳变量PATH
)。- 取决于安装的默认设置。
当您从父目录(包含输入脚本的目录)运行util.py
时,
from AReport import AReport
它将从父目录中查找AReport
模块,但它不在那里,因为只有report
包直接位于/Path/to/Parent目录下。这就是为什么Python会引发ModuleNotFoundError
。如果您这样做了
from report.AReport import AReport
它将正常工作,因为report
包位于/Path/To/Parent下。
如果要在导入时避免使用report.
前缀,一种选择是将report
包添加到sys.path
的util.py
:
import sys
sys.path.append("./report")
print(sys.path)
# should now show the /path/to/Parent/report on the list
然后,您的from AReport
导入现在将起作用。另一种选择是在运行util.py
之前将/Path/to/Parent/Report添加到PYTHONPATH
环境变量中。
export PYTHONPATH=$PYTHONPATH:/path/to/Parent/report
我通常使用PYTHONPATH
选项进行测试,因此不需要修改代码。
相关文章