You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加载Jupyter Notebook中用自定义类保存的joblib文件

报错原因

joblib 底层依赖 pickle 实现序列化,序列化自定义类实例时不会存储类的完整实现代码,仅会记录类所属的模块名、类名两个核心信息。反序列化时会自动到对应模块中检索匹配的类定义:

  • 你在原 Jupyter Notebook 中定义 Duck 类时,该类默认归属于 __main__ 模块,当前 Notebook 运行时 __main__ 模块存在 Duck 定义,因此可以正常加载
  • 切换到新的 Notebook 或 .py 脚本后,新的运行环境中 __main__ 模块没有预先定义 Duck 类,因此会抛出属性找不到的错误
解决方法

方法1:预定义同版本类(临时适配)

反序列化操作执行前,先在当前运行环境中定义和序列化时完全一致的 Duck 类,类的属性、方法、继承关系都不能有差异,示例代码如下:

# 先完整定义和序列化时一模一样的Duck类
class Duck:
    def quack(self):
        print("Quack!")

# 再执行加载逻辑
import joblib
my_duck = joblib.load("my_duck.joblib")

方法2:公共模块托管类(推荐方案)

把自定义类的实现写到单独的公共 .py 文件中,序列化、反序列化场景都从该公共模块导入类使用,彻底避免跨环境找不到类的问题:

  1. 新建 duck_utils.py 文件,写入 Duck 类的完整实现
  2. 序列化时的代码:
from duck_utils import Duck
import joblib

duck = Duck()
joblib.dump(duck, "my_duck.joblib")
  1. 任意新环境反序列化时的代码:
from duck_utils import Duck
import joblib

my_duck = joblib.load("my_duck.joblib")

方法3:手动注册类到__main__模块

如果不想修改类的引入方式,可以手动把类注册到运行环境的 __main__ 模块中,示例代码如下:

import __main__
import joblib

# 定义Duck类
class Duck:
    def quack(self):
        print("Quack!")

# 手动注册到__main__模块
__main__.Duck = Duck

# 加载序列化文件
my_duck = joblib.load("my_duck.joblib")
注意事项
  • 类定义必须和序列化时完全一致,如果类的方法、属性结构发生了变更,加载后的实例调用时可能会出现不可预期的异常
  • 不要加载来源不明的 joblib/pickle 序列化文件,这类文件可能包含恶意执行代码,存在安全风险

内容的提问来源于stack exchange,提问作者J. Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 07:57:03