Найти - Пользователи
Полная версия: Проблема с распикливанием файла
Начало » Python для новичков » Проблема с распикливанием файла
1
holysoul
Пытаюсь распиклить файл, на что получаю TypeError:

TypeError: ('object.__new__(X): X is not a type object (classobj)', <function _reconstructor at 0xf7d53614>, (<class packet.RequestContainer at 0xf7b9da4c>, <type ‘object’>, None))

У меня есть подозрение, почему так может быть. Вопрос, в правильном ли направлении я размышляю?

В данный файл запикливается объект класса RequestContainer ( который является наследником другого базового класса ):

1. class BaseRequestContainer(object)
2. class RequestContainer(BaseRequestContainer)

При распикливании таких конструкций, Exception возникает в copy_reg.

def _reconstructor(cls, base, state):
if base is object:
obj = object.__new__(cls)
else:
obj = base.__new__(cls, state)
base.__init__(obj, state)
return obj

в момент obj = object.__new__(cls).
В качестве cls - RequestContainer, _base у которого типа - BaseRequestContainer, а не типа object.
Правильно ли я понимаю, что в этот момент логика пытается создать класс, базовым классом которого является object, однако в нашем случае базовый класс для нового объекта - RequestContainer, и в результате этого несоответствия и возникает данный TypeError?
Андрей Светлов
Неправильно
>>> import pickle
>>> class A(object):
... pass
...
>>> class B(A):
... pass
...
>>> b = B()
>>> pickle.loads(pickle.dumps(b, pickle.HIGHEST_PROTOCOL))
<__main__.B object at 0x026A3C90>
Ищите ошибку в другом месте.
truporez
Возможно объект восстанавливается из другого модуля, имеющего путь отличный от модуля выполнившего dump.
z.b. один модуль импортит объект как mod1.mod2, а другой mod0.mod1.mod2
holysoul
Андрей Светлов
Ищите ошибку в другом месте.
Ок, спасибо, буду искать.
holysoul
truporez
z.b. один модуль импортит объект как mod1.mod2, а другой mod0.mod1.mod2
Не совсем понятно, что это значит.
holysoul
Еще одна мысль появилась по этому поводу.

У меня в классе B() есть атрибут s.atr, который является экземпляром другого класса (например, класса C), описанного в отдельном модуле. Запикливание объекта класса B происходит во время работы программки, в которой, соответственно, все необходимые модули загружены. Поэтому при запикливании ошибок не возникает.
А вот распикливание полученного файла происходит отдельно, из другого модуля (при этом программка может и не быть запущена в данный момент). Так вот в этом другом модуле не импортирован класс C, экземпляром которого является атрибут atr. Может быть, поэтому ничего не получается?

Теперь ближе к истине?
Андрей Светлов
Не совсем так. Если класса нет (а pickle сохраняет полный путь включая модули) - делается импорт. Если импортировать нельзя - ошибка. Это работает рекурсивно - поэтому применяется и к атрибутам.
Как правильно написал trupores - ваш RequestContainer при распаковке должен быть доступен по тому же “длинному имени”, что использовался при упаковке.
Если вы в упаковщике писали
from package.module import RequestContainer
r = RequestContainer()
в распаковщике тоже должно работать
from package.module import RequestContainer
holysoul
Андрей Светлов
Не совсем так. Если класса нет (а pickle сохраняет полный путь включая модули) - делается импорт. Если импортировать нельзя - ошибка. Это работает рекурсивно - поэтому применяется и к атрибутам.
Как правильно написал trupores - ваш RequestContainer при распаковке должен быть доступен по тому же “длинному имени”, что использовался при упаковке.
Если вы в упаковщике писали
from package.module import RequestContainer
r = RequestContainer()
в распаковщике тоже должно работать
from package.module import RequestContainer
Понятно, спасибо! :)
Я-таки нашла вчера, в чем проблема была. :)
Класс, объект которого консервировался, был объявлен как “class B(object):”. А при распикливании использовалось описание этого класса в другом модуле. А в нем этот класс был объявлен просто как “class B:” Соответственно, и возникала ошибка. :)
А мое предположение о том, что не хватает импорта другого класса, тоже верным оказалось. Только я как бы предвидела будущее. Потому что как только я исправила ошибку с TypeError, тут же появилась ImportError: No module named LogicClient. :)
Зато теперь я знаю, что нужно делать.

Большое спасибо Вам, Андрей, и Вам, truporez, за помощь!!! Благодаря вам мне стали понятней некоторые моменты в программировании на Питоне, которые раньше были не понятны! =)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB