Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 19, 2010 14:00:22

holysoul
От:
Зарегистрирован: 2010-01-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с распикливанием файла

Пытаюсь распиклить файл, на что получаю 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?



Офлайн

#2 Янв. 19, 2010 15:36:24

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Проблема с распикливанием файла

Неправильно

>>> 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>
Ищите ошибку в другом месте.



Офлайн

#3 Янв. 19, 2010 16:25:44

truporez
От:
Зарегистрирован: 2009-05-08
Сообщения: 266
Репутация: +  6  -
Профиль   Адрес электронной почты  

Проблема с распикливанием файла

Возможно объект восстанавливается из другого модуля, имеющего путь отличный от модуля выполнившего dump.
z.b. один модуль импортит объект как mod1.mod2, а другой mod0.mod1.mod2



Офлайн

#4 Янв. 19, 2010 16:47:02

holysoul
От:
Зарегистрирован: 2010-01-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с распикливанием файла

Андрей Светлов
Ищите ошибку в другом месте.
Ок, спасибо, буду искать.



Офлайн

#5 Янв. 19, 2010 16:48:22

holysoul
От:
Зарегистрирован: 2010-01-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с распикливанием файла

truporez
z.b. один модуль импортит объект как mod1.mod2, а другой mod0.mod1.mod2
Не совсем понятно, что это значит.



Офлайн

#6 Янв. 19, 2010 16:55:01

holysoul
От:
Зарегистрирован: 2010-01-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с распикливанием файла

Еще одна мысль появилась по этому поводу.

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

Теперь ближе к истине?



Офлайн

#7 Янв. 20, 2010 00:32:59

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Проблема с распикливанием файла

Не совсем так. Если класса нет (а pickle сохраняет полный путь включая модули) - делается импорт. Если импортировать нельзя - ошибка. Это работает рекурсивно - поэтому применяется и к атрибутам.
Как правильно написал trupores - ваш RequestContainer при распаковке должен быть доступен по тому же “длинному имени”, что использовался при упаковке.
Если вы в упаковщике писали
from package.module import RequestContainer
r = RequestContainer()
в распаковщике тоже должно работать
from package.module import RequestContainer



Офлайн

#8 Янв. 20, 2010 10:15:24

holysoul
От:
Зарегистрирован: 2010-01-19
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с распикливанием файла

Андрей Светлов
Не совсем так. Если класса нет (а 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, за помощь!!! Благодаря вам мне стали понятней некоторые моменты в программировании на Питоне, которые раньше были не понятны! =)



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version