从莳萝pickle文件中获取源代码(OSError:无法提取源代码)



进一步阅读本文,我们如何从pickle文件中获取源代码

我尝试使用getsource(阅读这篇文章后),但只有当类在同一会话中定义时才有效,下面是我尝试的代码

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

f = Foo(5)

with open('foo.pkl', 'wb') as pkl:
dill.dump(f, pkl)
with open('foo.pkl', 'rb') as pkl:
b = dill.load(pkl)
print(b)
#sFoo = dill.source.getsource('foo.pkl') ## error
#sFoo = dill.source.getsource(b) ## error
#sFoo = dill.source.getsource(b.bar) ## error

错误的细节使用sFoo = dill.source.getsource(b)时错误为OSError: could not extract source code

使用sFoo = dill.source.getsource(b.bar)时错误为OSError: could not extract source code

从这里进一步阅读,我从标准python控制台运行代码,而不是使用jupyter,仍然没有得到正确的结果,但比以前更好,这次没有错误

dill.source.getsource(b)

输出如下

'import dillndill.loads(b'\x80\x03cdill._dill\n_create_type\nq\x00(cdill._dill\n_load_type\nq\x01X\x04\x00\x00\x00typeq\x02\x85q\x03Rq\x04X\x03\x00\x00\x00Fooq\x05h\x01X\x06\x00\x00\x00objectq\x06\x85q\x07Rq\x08\x85q\t}q\n(X\n\x00\x00\x00__module__q\x0bX\x08\x00\x00\x00__main__q\x0cX\x03\x00\x00\x00barq\rcdill._dill\n_create_function\nq\x0e(h\x01X\x08\x00\x00\x00CodeTypeq\x0f\x85q\x10Rq\x11(K\x02K\x00K\x02K\x02KCC\n|\x01|\x00j\x00\x17\x00S\x00q\x12N\x85q\x13X\x01\x00\x00\x00yq\x14\x85q\x15X\x04\x00\x00\x00selfq\x16X\x01\x00\x00\x00xq\x17\x86q\x18X\x07\x00\x00\x00<stdin>q\x19h\rK\x02C\x02\x00\x01q\x1a))tq\x1bRq\x1cc__builtin__\n__main__\nh\rNN}q\x1dtq\x1eRq\x1fh\x14K\x01X\x07\x00\x00\x00__doc__q NX\r\x00\x00\x00__slotnames__q!]q"utq#Rq$)\x81q%.')n'

在注释中进一步建议使用dill.source.getsource(dill.detect.code(b)),但这会导致错误为TypeError: None is not a module, class, method, function, traceback, frame, or code object

然后当我尝试dill.source.getsource(b.bar)时,我得到了完美的结果

>>> dill.source.getsource(b.bar)
'  def bar(self, x):n    return x+self.y       n'

现在我得到了

我们可以做的是首先使用下面的代码跟踪pickle文件,这将给出类中所有函数的列表,然后我们可以使用getsource单独检测它们的源代码。

dill.detect.trace(True)
dill.pickles(b)

最新更新