Форум сайта python.su
Прошу помочь с проблемой. Создаю объект, в нем свойство - список ссылок на другие объекты. Проблемы: объект каким то образом добавляет себя в этот список (ничего такого даже не подразумевалось делать). Кроме того при использовании модуля 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 умеет сохранять древовидные структуры с циклическими ссылками, так что проблема не в этом.
Отредактировано (Дек. 8, 2009 07:29:45)
Офлайн
Извиняюсь за неудачный пример (просто взял код как он был). Посути исправление ChildrenList = на self.ChildrenList = (невнимательность меня погубит) помогло исправить проблему, но почему это произошло я так и не понял.
Офлайн
Я чего то не понимаю или 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
Офлайн
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Вы стали использовать instance variable вместо class variable. Другими словами, ChildrenList раньше был глобальным.
Извиняюсь за неудачный пример (просто взял код как он был). Посути исправление ChildrenList = на self.ChildrenList = (невнимательность меня погубит) помогло исправить проблему, но почему это произошло я так и не понял.
Офлайн
Возможно это выше моего понимания: вот ничего не работало, просто ни в какую. Обвешал все это чудо логгером со всех сторон, ничего не понятно было. Все примеры работали, а мой код никак (этот класс был завернут в большую гуевину). Сейчас убрал логгер и, о чудо, все заработало. Колдовство да и только. Извиняюсь за отнятое время.
Офлайн
Для того, чтобы непоняток таких не оставалось советую использовать какой-нибудь dvcs(git, mercurial, bazaar) и коммитить почаще. Тогда можно будет разобраться что именно произошло.
У git-а даже есть специальное средство для таких поисков - git-bisect.
Или у вас есть и неработающий код? Тогда давайте разберемся почему он не работает.
Офлайн
Если вы инициализируете поля класса вне конструктора или методов, то это поле будет общим (т.е. поле класса а не объекта).
Офлайн