засолите ошибку груза "__ init __ (), берет точно 2 аргумента (1 данный)"

Моя проблема - то, что таможенный класс был спасен с pickle.dump, так как эти файлы были сохранены, таможенный класс был изменен и теперь когда я использую pickle.load, я получаю эту ошибку. Действительно ли это - проблема с сохраненным файлом?

Ошибка:

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)

Есть ли что-нибудь, что я могу сделать, чтобы загрузить файл?

Кодекс

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

даст мне ошибку.


Here is some minimal code which can reproduce Ошибка:

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)
3
добавлено отредактировано
Просмотры: 2
nl ja de
Что-то подозрительно здесь. __ init __ shouldn' t быть названным. Ваш класс - или новый стиль в старинном стиле? Кроме того, вы солили класс или экземпляр класса ? Ваш класс имеет __ getinitargs __ метод?
добавлено автор mgilson, источник
@MartijnPieters - по-видимому, я can' t даже вкладывают мои комментарии быстрее, чем вы: p
добавлено автор mgilson, источник
@MartijnPieters - я предполагаю that' s, почему у меня было достаточно времени, чтобы написать маленький сценарий, чтобы доказать мне что __ init __ wasn' t на самом деле названный:-p - И я беру его, вы подразумеваете, что были в такси, нет что вы были такси (поскольку это будет немного странно...),
добавлено автор mgilson, источник
что аргументы делает вашу текущую версию класса, ожидают (в init ) против иллюстрировавшего примерами объекта, можно ли дать некоторые примеры?
добавлено автор Joshua Burns, источник
Ваш класс осуществляет __ getinitargs __() или __ getnewargs __() вообще (по крайней мере, когда это было солео)?
добавлено автор Martijn Pieters, источник
@wDroter: Это - важная деталь.
добавлено автор Martijn Pieters, источник
@mgilson: Я обвиняю НАСТОЛЬКО теряющий сознание там в течение секунды для понижения в в том предложении.
добавлено автор Martijn Pieters, источник
@mgilson: И это было с мной являющийся такси, когда это было отправлено!:-P
добавлено автор Martijn Pieters, источник
Есть ли что-либо, что я могу сделать, чтобы загрузить эти старые классы; /
добавлено автор wDroter, источник
Класс не имел __ getinitargs __ (), когда он был соле. Это было добавлено как часть изменения.
добавлено автор wDroter, источник

3 ответы

Учитывая изобретенный код, который я опубликовал от вашего имени в вопросе, мы можем "зафиксировать" эту ошибку как:

with open('junk','rb') as f:
    try:
        obj = pickle.load(f)
    except Exception as e:
        print e
        position = f.tell()
        a = foo.__getinitargs__
        del foo.__getinitargs__
        f.seek(position)
        obj = pickle.load(f)
        foo.__getinitargs__ = a

    print str(obj)

Теперь мы видим, что случай был не соле и больше не имеет признак b .

2
добавлено
@MartijnPieters - Да, Следовательно мой комментарий к вашему ответу, "Хотя это [ваш ответ] является, вероятно, намного лучшим способом пойти о выполнении его"
добавлено автор mgilson, источник
На самом деле мой первоначальный метод также работает и является немного меньшим количеством hacky, по моему мнению. Расширенный, чтобы указать, что оба метода действительно решают проблему OP.
добавлено автор Martijn Pieters, источник
Да, проверял это снова против вашего обновления в качестве примера, и оно, конечно, работает!
добавлено автор Martijn Pieters, источник

Если вы добавили __ getinitargs __() тогда Вам решать, чтобы удостовериться, что ваш новый класс может обращаться с аргументами, переданными к __ init __() . Старые данные, которые не имеют __ getinitargs __ данные, будут все еще вести, чтобы __ init __ , чтобы быть названными, но с <�ними> не аргументы.

Приведите аргументы __ init __ дополнительный через аргументы ключевого слова:

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 __() , чтобы преобразовать внутреннее состояние по мере необходимости.

Альтернативно, временно удаляют __ getinitargs __ метод от класса:

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

и повторно свалите свои соленые огурцы от теперь-загруженных-объектов с __ getinitargs __ восстановленный.

Я проверил оба метода, и в обоих случаях старые данные загружаются правильно, и можно тогда свалить объекты снова к новому рассолу, регистрируют с __ getinitargs __ очень хорошо.

2
добавлено
@MartijnPieters - Сделал вы пробуете код, который я разместил на OP' s имя, чтобы воспроизвести проблему? Это только работает на старый классы стиля, поэтому удостоверьтесь you' ре используя python2.x
добавлено автор mgilson, источник
Интересно, было ли бы возможно = класс. __ getinitargs __; класс del. __ getinitargs __; pickle.load (); класс. __ getinitargs __ = . Другими словами, удалите __ getinitargs __ , нерассол и затем участок обезьяны __ getinitargs __ назад на... (хотя это - вероятно, намного лучший способ пойти о выполнении его),
добавлено автор mgilson, источник
@mgilson: Да, проверяя с классами в старинном стиле здесь. Must' ve пропустил что-то; мой начальный тест didn' t включают аргументы в пользу __ init __ (вне сам ) вообще.
добавлено автор Martijn Pieters, источник
@mgilson: вещь, я испытывал это, но я не могу воспроизвести проблему OP здесь. Это только происходит, если соленые данные на самом деле имеют пустой __ getinitargs __ соленые ценности, я подозреваю. В этом случае данные бесполезны так или иначе.
добавлено автор Martijn Pieters, источник
@wDroter: That' s, с чем мы пытаемся помочь вам здесь.
добавлено автор Martijn Pieters, источник
Моя проблема - то, что предыдущая версия класса уже была солеа, и я пытаюсь загрузить те файлы.
добавлено автор wDroter, источник

Вы могли бы хотеть изменить таможенный класс, чтобы произвольно потребовать второго параметра. Это воздержалось бы от совместимости премии с вашими солеными объектами.

1
добавлено
Спасибо, однако они уже были солеы как предыдущая версия класса.
добавлено автор wDroter, источник