使用 dill 序列化含自定义类实例的列表后,反序列化对象的 isinstance() 判断会返回 false,这是因为 dill 默认重新构造类对象而非引用原类;启用 byref=true 或改用 pickle 可修复此问题。
使用 dill 序列化含自定义类实例的列表后,反序列化对象的 isinstance() 判断会返回 false,这是因为 dill 默认重新构造类对象而非引用原类;启用 byref=true 或改用 pickle 可修复此问题。
在 Python 中,isinstance(obj, cls) 的底层逻辑依赖于 obj.__class__ is cls(或其继承链中的类对象身份一致性)。而 dill 作为 pickle 的增强版,设计目标是序列化更广泛的对象类型(如 lambda、嵌套函数、交互式会话中的类等),其默认行为是深度序列化类定义本身——即在反序列化时动态重建一个同名、同结构的新类对象,而非复用原始模块中已存在的 MyClass。
这导致关键差异:
- x[0].__class__ 是模块中定义的原始 MyClass;
- y[0].__class__ 是 dill 在加载时新创建的 MyClass 副本(尽管名称、代码相同,但内存地址不同);
- 因此 isinstance(y[0], MyClass) 返回 False,因为 y[0].__class__ is not MyClass。
可通过 id() 验证这一现象:
print(id(MyClass)) # 例如:140430969773264 print(id(x[0].__class__)) # 同上 → 引用同一对象 print(id(y[0].__class__)) # 不同值 → 新建类对象
✅ 解决方案一:启用 byref=True(推荐用于需 dill 功能的场景)
设置 dill.settings['byref'] = True 后,dill 将优先通过模块路径(如 '__main__.MyClass')按引用方式加载类,行为与 pickle 一致:
import dill
from pathlib import Path
class MyClass:
def __init__(self) -> None:
pass
dill.settings['byref'] = True # 关键设置!
path = Path('test/test.pkl')
path.parent.mkdir(exist_ok=True)
x = [MyClass()]
dill.dump(x, path.open('wb'))
y = dill.load(path.open('rb'))
print(isinstance(x[0], MyClass)) # True
print(isinstance(y[0], MyClass)) # True ✅⚠️ 注意:byref=True 对位于 __main__ 模块(如脚本直接运行)的类有效,但若类定义在临时环境(如 Jupyter 单元格)、无稳定模块路径时,仍可能失效。此时需确保类定义在可导入的 .py 文件中,并以 import 方式引用。
✅ 解决方案二:改用标准库 pickle(轻量可靠)
若无需 dill 特有的高级序列化能力(如闭包、动态生成类),pickle 是更安全、兼容性更好的选择:
import pickle
from pathlib import Path
# ... MyClass 定义同上 ...
x = [MyClass()]
path = Path('test/test.pkl')
path.parent.mkdir(exist_ok=True)
with path.open('wb') as f:
pickle.dump(x, f)
with path.open('rb') as f:
y = pickle.load(f)
print(isinstance(y[0], MyClass)) # True ✅总结
| 方案 | 适用场景 | 是否保持 dill 全功能 | 类身份一致性 |
|---|---|---|---|
| dill.settings['byref'] = True | 需 dill 支持复杂对象 + 要求 isinstance 正常工作 | ✅ 是 | ✅ 是 |
| pickle | 仅需序列化常规类/数据结构 | ❌ 否(功能更少) | ✅ 是 |
| 默认 dill(byref=False) | 必须序列化不可导入对象(如交互式定义的类) | ✅ 是 | ❌ 否 |
始终优先考虑 byref=True 作为 dill 的稳健配置,它在保留强大序列化能力的同时,恢复了与 pickle 一致的类引用语义,避免 isinstance 等类型检查意外失效。

















