Почему я получаю ошибку в том, что мой класс определяет __slots__ при попытке оформления объекта?

StackOverflow https://stackoverflow.com/questions/2204155

  •  18-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь зарисовать объект (новый стиль) класса, который я определил. Но я получаю следующую ошибку:

>>> with open('temp/connection.pickle','w') as f:
...   pickle.dump(c,f)
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python2.5/pickle.py", line 1362, in dump
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.5/pickle.py", line 419, in save_reduce
    save(state)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/usr/lib/python2.5/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/usr/lib/python2.5/copy_reg.py", line 76, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

Я явно не определил __slots__ в моем классе. Что -то я неявно определил это? Как мне это обойти? Мне нужно определить __getstate__?

Обновлять: gnibbler выбрал хороший пример. Класс объекта, который я пытаюсь, окрашивает розетку. (Это приходит мне сейчас, когда) определяют гнезда __slots__ и не __getstate__ по уважительной причине. Я предполагаю, что, как только процесс заканчивается, другой процесс не может заблокировать и использовать подключение к сокету предыдущего процесса. Итак, пока я принимаю Алекс МартеллиОтличный ответ, мне придется использовать другую стратегию, чем маринование, чтобы «поделиться» ссылкой на объект.

Это было полезно?

Решение

Класс определяет __slots__ (и не __getstate__) может быть вашим классом предков, либо классом (или классом предков) атрибута, либо вашим предметом, прямо или косвенно: по сути, класс любого объекта в направленный график ссылок с вашим объектом в качестве корня, так как маринован должен сохранить весь график.

Простое решение вашего затруднения - использовать протокол -1, что означает «лучший протокол, может использовать рассол»; По умолчанию-древний протокол на основе ASCII, который накладывает это ограничение о __slots__ против __getstate__. Анкет Рассмотреть возможность:

>>> class sic(object):
...   __slots__ = 'a', 'b'
... 
>>> import pickle
>>> pickle.dumps(sic(), -1)
'\x80\x02c__main__\nsic\nq\x00)\x81q\x01.'
>>> pickle.dumps(sic())
Traceback (most recent call last):
  [snip snip]
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
>>> 

Как вы видите, протокол -1 принимает __slots__ с шагом, в то время как протокол по умолчанию дает то же исключение, которое вы видели.

Проблемы с протоколом -1: Он создает двоичную строку/файл, а не ASCII, как протокол по умолчанию; Полученный маринованный файл не будет загружен достаточно древними версиями Python. Преимущества, помимо ключевого One WRT __slots__, Включите более компактные результаты и лучшие производительность.

Если вы вынуждены использовать протокол по умолчанию, вам нужно определить, какой класс дает вам проблемы и именно почему. Мы можем обсудить стратегии, если это так (но если вы можете использовать -1 Протокол, это намного лучше, что его не стоит обсуждать ;-), а простая проверка кода в поисках неприятного класса/объекта оказывается слишком сложным (я имею в виду некоторые трюки на основе глубоководства, чтобы получить полезное представление всего графика, в Случай вам интересно).

Другие советы

Возможно, атрибут вашего экземпляра использует __slots__

Например, socket имеет __slots__ Так что это не может быть мариновано

Вам нужно определить, какой атрибут вызывает ошибку и написать свою собственную__getstate__ а также __setstate__ игнорировать этот атрибут

Из PEP 307:

А __getstate__ Метод должен вернуть снятому значению, представляющему состояние объекта, не ссылаясь на сам объект. Если нет __getstate__ Существует метод, используется реализация по умолчанию, которая возвращает self.__dict__.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top