我在名为疾病树.py 的文件中定义了一个名为疾病树的类。我已经使用这个类有一段时间了。在不同的工作流程中,我生成了此类的实例,并使用 joblib 写入文件。
我现在正在尝试构建一个模块,其中包含此代码。 我的目录结构如下所示:
/
/models
__init__.py
models.py
diseaseTree.py
/plots
__init__.py
plots.py
__init__.py
main.py
在 models/init.py 中我有:
from .models import DatabaseConnector
from .diseaseTree import DiseaseTree
在plots/plots.py中,我有:
from models import DatabaseConnector
from models import DiseaseTree
import joblib
with open("/data/projects/classifiers/data/diseaseTree.joblib", "rb") as file:
mainTree = joblib.load(file)
进口有效。当我尝试加载 joblib 文件时,我得到:
ModuleNotFoundError: No module named 'diseaseTree'
据我所知,它与疾病树的初始实例转储到文件时的酸洗过程有关,但我不知道如何纠正这个问题。如果我专门将该类添加到 sys.modules 中,我可以欺骗它,即这样做:
from models import DiseaseTree
temp_module = types.ModuleType('diseaseTree')
temp_module.DiseaseTree = DiseaseTree
sys.modules['diseaseTree'] = temp_module
然后加载joblib文件就可以了。如果我每次想要加载疾病树实例时都必须诉诸于此,那么我不认为首先将所有内容放入模块中的意义。
如何转换/更新 joblib 文件中存储的实例,或优雅地处理这个问题?
问题在于 Python 处理模块导入和 pickling 的方式。当您使用
joblib
保存类的任何实例时,该文件将存储该类最初定义的模块路径。如果路径已更改,您将得到 ModuleNotFoundError
。
我建议确保模块路径在保存和加载之间保持一致。
还可以在保存或加载时尝试使用完全限定的类名,其中在路径中包含模块名称,例如: 保存时:
import joblib
from models.diseaseTree import DiseaseTree
tree = DiseaseTree()
joblib.dump(tree, "/data/projects/classifiers/data/diseaseTree.joblib")
加载时
import joblib
from models.diseaseTree import DiseaseTree
with open("/data/projects/classifiers/data/diseaseTree.joblib", "rb") as file:
mainTree = joblib.load(file)
如果
joblib
仍然导致 havic,您可以使用 dill
库,因为它在酸洗方面更加强大