如何使用dill序列化导入模块的函数 封装完整内容无需上下文依赖
注意:你提供的foo.py代码存在笔误,内部定义的函数名为qqq,和fun.py中导入的ppp不一致,实际测试需要先统一函数名。
问题原因
导入的外部模块函数序列化后仅存引用,核心有两个原因:
- 你传入了
byref=True参数:该参数的作用是强制dill对模块级顶层对象优先存储导入引用,而非完整序列化内容,和需求完全相反。 - dill默认会识别从其他模块导入的顶层函数,优先用「模块名+函数名」的引用方式存储,避免重复序列化相同模块内容。
实现方案
方案1:去掉byref=True参数(最简便)
recurse=True已经可以保证序列化函数的全部依赖内容,不需要开启byref,直接修改序列化参数即可:
print(dill.dumps(ppp, protocol=4, recurse=True))
修改后ppp的序列化结果长度会和当前本地定义的qqq接近,已经包含完整的函数字节码,反序列化时不需要依赖foo.py文件。
方案2:手动修改函数所属模块标识(兼容性更强)
如果修改参数后仍有部分场景存储引用,可以临时修改导入函数的__module__属性,强制dill按本地函数规则序列化:
import dill from foo import ppp # 备份原模块属性 origin_module = ppp.__module__ ppp.__module__ = __name__ # 序列化 ppp_serialized = dill.dumps(ppp, protocol=4, recurse=True) print(ppp_serialized) # 恢复原属性不影响当前进程运行 ppp.__module__ = origin_module
方案3:全局配置dill关闭模块引用
如果需要批量序列化多个导入函数,可以直接修改dill全局配置,不需要每次传参:
dill.settings['byref'] = False dill.settings['recurse'] = True # 后续直接调用dumps即可 print(dill.dumps(ppp, protocol=4))
验证方法
将序列化后的字节保存到文件,在没有foo.py的全新环境下执行dill.loads反序列化,即可直接调用函数,无需依赖原模块上下文。
内容的提问来源于stack exchange,提问作者James Pinkerton
相关产品推荐
相关产品推荐

