Найти - Пользователи
Полная версия: Ссылки на объекты и сериализация
Начало » Python для экспертов » Ссылки на объекты и сериализация
1
dartNNN
Прошу помочь с проблемой. Создаю объект, в нем свойство - список ссылок на другие объекты. Проблемы: объект каким то образом добавляет себя в этот список (ничего такого даже не подразумевалось делать). Кроме того при использовании модуля pickle сохраняется сам объект, но не сохраняются объекты на которые были сделаны ссылки.
Код выглядит следущим образом:
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.MainNote = Note('main', 'undef', None)

def dump(self):
f=open(self.workdir+"\\Notes\\" + self.getUser(),"wb")
pickle.dump(self.MainNote,f) #сохраняю объект, в ктором есть ссылки
f.close()


class Note():
ChildrenList = [] #список ссылок

def __init__(self, notename, user, parent):
self.Name = str(notename)
self.User = str(user)
self.Text = self.Name + self.NewNoteTip
self.Parent = parent

ChildrenList = []

def addChildNote(self,notename):
childNote=Note(notename,self.User,self)
self.ChildrenList.append(childNote) # добавляется ссылка на объект
return childNote

def childs(self):
return self.ChildrenList

def getNoteByName(self,notename):
notename = str(notename)
if self.name() == notename:
return self
for x in self.childs(): # здесь возникает проблема: так как в списке есть и сам объект возникает бесконечная рекурсия (и много других проблем в разных частях кода).
childRes = x.getNoteByName(notename)
if childRes != None:
return childRes
else:
return None
return None
Андрей Светлов
Пример не работающий.
В Note.__init__ self.Text = self.Name + self.NewNoteTip, а self.NewNoteTip не определен.
ChildrenList = - смысла не имеет, похоже забыли self.
PyQt для piclke - совсем не при делах, можно для демонстрации использовать консоль.

Резюме: сделайте короткий пример с иллюстрацией вашей беды и спросите еще раз.
pickle умеет сохранять древовидные структуры с циклическими ссылками, так что проблема не в этом.
dartNNN
Извиняюсь за неудачный пример (просто взял код как он был). Посути исправление ChildrenList = на self.ChildrenList = (невнимательность меня погубит) помогло исправить проблему, но почему это произошло я так и не понял.
dartNNN
Я чего то не понимаю или python и колдовство - слова синонимы? Следующий код работает без нареканий:

import pickle
class A():
ref = []
def __init__(self):
self.ref.append(B())

class B():
int = 10
def __init__(self):
self.int = 99

if __name__ == '__main__':
test = A()
f = open('test','wb')
pickle.dump(test,f)
f.close()
print(test.ref[0].int)
del test
f=open('test','rb')
test = pickle.load(f)
f.close()
print(test.ref[0].int)
А мое творение никак:

class Note():
Text = ''
NewNoteTip = "\n\nDescribe here your note"
Name = ""
ChildrenList = []
User = ""
Parent = None

def __init__(self, notename, user, parent):
self.Name = str(notename)
self.User = str(user)
self.Text = self.Name + self.NewNoteTip
if parent != None:
self.Parent = parent
else:
self.Parent = self
self.ChildrenList = []

def note(self):
return self.Text

def save(self, text):
self.Text = str(text)

def name(self):
return self.Name

def addChildNote(self,notename):
childNote=Note(notename,self.User,self)
self.ChildrenList.append(childNote)
return childNote

def delNote(self,note):
self.ChildrenList.remove(note)

def childs(self):
return self.ChildrenList

def getNoteByName(self,notename):
notename = str(notename)
if self.name() == notename:
return self
for x in self.childs():
childRes = x.getNoteByName(notename)
if childRes != None:
return childRes
else:
return None
return None

def parent(self):
return self.Parent
Причем, если пиклить последний в иерархии объект, то выше идущие сохраняются (благодаря ссылке в self.Parent), на ссылки в self.ChildrenList видимо наплевать.
Проверено, что во время выполнения скрипта все ссылки рабочие.
И, если это важно, этот класс я востанавливал по памяти, а ныне утерянный вариант работал без запинок
Даже не представляю себе как такое может быть и в чем ошибка.
Буду рад любой помощи.
Ed
dartNNN
Я чего то не понимаю или python и колдовство - слова синонимы?
Вы чего-то явно не понимаете :)

Вы бы примерчик какой дали, а то телепатически трудно осознать что у вас не работает.
Вот, например, такой код у меня работает:
note = Note("MainNote", "user", None)
note.addChildNote("ChildNote")
f = open('test.pickle','wb')
pickle.dump(note, f)
f.close()
print "Before:", note.Name, note.childs()[0].Name
del note
f=open('test.pickle','rb')
note = pickle.load(f)
f.close()
print "After:", note.Name, note.childs()[0].Name
Выдает вот это:
Before: MainNote ChildNote
After: MainNote ChildNote
Андрей Светлов
dartNNN
Извиняюсь за неудачный пример (просто взял код как он был). Посути исправление ChildrenList = на self.ChildrenList = (невнимательность меня погубит) помогло исправить проблему, но почему это произошло я так и не понял.
Вы стали использовать instance variable вместо class variable. Другими словами, ChildrenList раньше был глобальным.
dartNNN
Возможно это выше моего понимания: вот ничего не работало, просто ни в какую. Обвешал все это чудо логгером со всех сторон, ничего не понятно было. Все примеры работали, а мой код никак (этот класс был завернут в большую гуевину). Сейчас убрал логгер и, о чудо, все заработало. Колдовство да и только. Извиняюсь за отнятое время.
Ed
Для того, чтобы непоняток таких не оставалось советую использовать какой-нибудь dvcs(git, mercurial, bazaar) и коммитить почаще. Тогда можно будет разобраться что именно произошло.
У git-а даже есть специальное средство для таких поисков - git-bisect.
Или у вас есть и неработающий код? Тогда давайте разберемся почему он не работает.
adnull
Если вы инициализируете поля класса вне конструктора или методов, то это поле будет общим (т.е. поле класса а не объекта).
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