泡菜装载错误"__init __()恰好接受2个参数(给定1个)" [英] pickle load error "__init__() takes exactly 2 arguments (1 given)"

查看:63
本文介绍了泡菜装载错误"__init __()恰好接受2个参数(给定1个)"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是自定义类已与pickle.dump一起保存,由于这些文件已保存,因此自定义类已更改,现在当我使用pickle.load时出现此错误.保存的文件有问题吗?

My issue is that a custom class has been saved with pickle.dump, since these files were saved the custom class has been changed and now when I use pickle.load I am getting this error. Is it a problem with the saved file?

错误:

File "/cprprod/extern/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
File "/cprprod/extern/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
file "/cprprod/extern/lib/python2.7/pickle.py", line 1070, in load_inst
self._instantiate(klass, self.marker())
File "/cprprod/extern/lib/python2.7/pickle.py", line 1060, in _instantiate
value = klass(*args)

我可以做些什么来加载文件吗?

Is there anything I can do to load the file?

代码

file = open(filename,'rb')
obj = pickle.load(file)

会给我错误.

以下是一些可以重现该错误的最小代码:

Here is some minimal code which can reproduce the error:

import pickle

class foo:
    def __init__(self,a):
        self.a = a

    def __str__(self):
        return str(self.a)

obj = foo(1)

with open('junk','wb') as f:
    pickle.dump(obj,f)

class foo:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def __str__(self):
        return '%s %s'%(self.a,self.b)

    def __getinitargs__(self):
        return (self.a,self.b)

with open('junk','rb') as f:
    obj = pickle.load(f)
    print str(obj)

推荐答案

如果添加了__getinitargs__(),则要确保您的新类可以处理传递给__init__()的参数.没有__getinitargs__数据的旧数据仍会导致调用__init__,但带有 no 参数.

If you added __getinitargs__() then it is up to you to make sure your new class can handle the arguments passed to __init__(). Old data that doesn't have the __getinitargs__ data will still lead to __init__ to be called but with no arguments.

通过关键字参数将__init__的参数设为可选:

Make the arguments to __init__ optional via keyword arguments:

def __init__(self, otherarg=None):
    if otherarg is None:
        # created from an old-revision pickle. Handle separately.
        # The pickle will be loaded *normally* and data will still be set normally
        return
    self.otherarg = otherarg

在加载旧式泡菜时,这些类的数据仍将恢复.您可以根据需要使用__setstate__()转换内部状态.

When loading the old-style pickle, the data for these classes will still be restored. You can use __setstate__() to transform the internal state as needed.

或者,从类中临时删除 __getinitargs__方法:

Alternatively, temporarily remove the __getinitargs__ method from the class:

initargs = foo.__getinitargs__.__func__
del foo.__getinitargs__
obj = pickle.load(f)
foo.__getinitargs__ = initargs

,然后从恢复的__getinitargs__中,将食物中的酱菜重新倾倒.

and re-dump your pickles from the now-loaded objects with __getinitargs__ reinstated.

我已经测试了这两种方法,并且在两种情况下都正确加载了旧数据,然后可以将对象再次转储到新的pickle文件中, __getinitargs__就很好了.

I've tested both methods and in both cases the old data is loaded correctly and you can then dump your objects again to a new pickle file with __getinitargs__ just fine.

这篇关于泡菜装载错误"__init __()恰好接受2个参数(给定1个)"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆