Python Pickling Slots Error

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

  File "/usr/lib/python2.6/copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

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

Я могу только предположить, что внутри моего экземпляра есть какой-то объект, который вызывает это. Есть ли способ получить больше информации? Как найти класс точного объекта, который вызывает эту ошибку?

11
задан Eric O Lebigot 1 March 2013 в 03:17
поделиться

1 ответ

Используйте двоичный протокол для травления (вместо старого ASCII, который вы, кажется, используете по умолчанию), и все будет в порядке. Обратите внимание:

>>> class ws(object):
...   __slots__ = 'a', 'b'
...   def __init__(self, a=23, b=45): self.a, self.b = a, b
... 
>>> x = ws()
>>> import pickle
>>> pickle.dumps(x, -1)
'\x80\x02c__main__\nws\nq\x00)\x81q\x01N}q\x02(U\x01aq\x03K\x17U\x01bq\x04K-u\x86q\x05b.'
>>> pickle.dumps(x)
Traceback (most recent call last):
    [[snip]]
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/copy_reg.py", line 77, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
>>> 

Как видите, протокол -1 (что означает «лучший, самый быстрый и самый компактный протокол») работает нормально, в то время как протокол по умолчанию 0 ( старый протокол ascii, полностью совместимый с Python 1.5 и ранее) дает именно то исключение, которое вы наблюдали.

Кроме того, -1 будет быстрее , а даст более компактные результаты - вам просто нужно убедиться, что вы правильно сохраняете и восстанавливаете двоичные строки, которые он создает. (так, например, если вы обрабатываете файл, обязательно откройте последний для wb , не только для w ).

Если по какой-то причине это универсальное решение недоступно для вас, есть уловки и уловки (например, подкласс pickle.Pickler , используйте непосредственно экземпляр вашего подкласса, а не базовый one, как pickle.dumps , переопределяет метод save , поэтому он отслеживает тип (obj) перед делегированием суперклассу), но при обновлении вправо, Самый современный протокол ( -1 гарантированно будет в любой данной версии Python наиболее продвинутым протоколом, который поддерживает эта версия) в любом случае будет хорошей идеей, если это вообще возможно.

13
ответ дан 3 December 2019 в 08:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: