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

从dill pickle文件提取源代码报OSError: could not extract source code如何解决

报错原因

dill.source.getsource 是对Python内置inspect.getsource的封装,它仅从当前运行环境的源码文件、交互式会话历史中查找目标对象的源代码,不会从pickle序列化文件内读取内容。你跨会话加载dill序列化的实例时,当前运行环境没有对应类的源码定义,因此触发提取失败报错。

另外注意不要直接把pickle文件路径传入getsource,该接口仅支持接收Python对象作为入参,不支持直接解析序列化文件。


实现方案

方案1:序列化阶段同步存储类源码

如果需要从序列化文件中直接读取源码,在序列化时就把类的源码和实例绑定存储即可:

import dill

class Foo(object):
    def bar(self, x):
        return self.y + x
    def __init__(self, y):
        self.y = y

# 序列化
f = Foo(5)
save_pkg = {
    "instance": f,
    "foo_source": dill.source.getsource(Foo)
}
with open('foo_with_source.pkl', 'wb') as pkl:
    dill.dump(save_pkg, pkl)

# 反序列化直接读取源码
with open('foo_with_source.pkl', 'rb') as pkl:
    load_pkg = dill.load(pkl)
print(load_pkg["foo_source"])

方案2:使用dill内置源码序列化接口

dill提供了dumpsource/loadsource专门用于序列化类/函数的源码,无需手动拼接存储逻辑:

import dill

class Foo(object):
    def bar(self, x):
        return self.y + x
    def __init__(self, y):
        self.y = y

# 序列化类源码
with open('foo_source.pkl', 'wb') as pkl:
    dill.dumpsource(Foo, pkl)

# 跨会话加载得到可直接运行的类
with open('foo_source.pkl', 'rb') as pkl:
    LoadedFoo = dill.loadsource(pkl)

# 正常使用类,也可直接提取源码
print(dill.source.getsource(LoadedFoo))
f = LoadedFoo(5)
print(f.bar(3))

方案3:序列化时强制按值存储类定义

如果需要保留实例的运行状态,同时支持加载后提取源码,序列化时开启by_value=True参数,让dill把类的完整定义(而非仅类引用路径)写入序列化文件:

import dill

class Foo(object):
    def bar(self, x):
        return self.y + x
    def __init__(self, y):
        self.y = y

f = Foo(5)
# 序列化时开启by_value=True
with open('foo_full.pkl', 'wb') as pkl:
    dill.dump(f, pkl, by_value=True)

# 跨会话加载
with open('foo_full.pkl', 'rb') as pkl:
    b = dill.load(pkl)

# 此时可正常提取类源码
print(dill.source.getsource(b.__class__))

内容的提问来源于stack exchange,提问作者sakeesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:39:03