Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > Как удалить все ссылки на объект?


Автор: yesint 15.1.2007, 12:35
Доброго времени суток!
Возник (как у новичка) такой вопрос:
Есть некий объект, который хранит в себе список других объектов:

class A:
  def __init__(self):
    self.L = []
  
  def addItem(self):
    temp = classB()
    self.L.append(temp)
    return(temp)

В програме стоит такое:

  a = A()
  item1 = a.addItem()

Задача: нужно каким-то образом сделать так, что при удалении переменной item1 удалялась и ссылка из списка внутри экземпляра а т.е. чтобы сам объект физически удалялся.
Сколько не бился не нашел как это сделать. 
Возможно ли такое и как?

Зарание спасибо!

Автор: albertn 15.1.2007, 13:58
Можно сделать чуток подругому. В список помещать оригинальный объект, а возвращать ссылку на этот объект, в котором указан исходный объект со списком и оригинальный элемент. Потом прото переопределяем метод __del__, и удаляем этот элемент из списка.
Единственный недостаток, что обращаться к оригинальному элементу придется через original. Хотя от этого можно избавиться при помощи переопределенных функций, которые будут обращаться к оригинальному объекту.
Код

class classB:
    def __del__(self):
        print "Оригинал на \"%s\" удален" % (self.value,)

    def __init__(self,value):
        self.value = value

class classC:
    def __del__(self):
        print "Ссылка на \"%s\" удалена" % (self.original.value,)
        try:
            self.parent.L.remove(self.original)
        except:
            print "Оригинал в базе не обранужен"

    def __init__(self,parent,original):
        self.parent = parent
        self.original = original

class A:
    def __init__(self):
        self.L = []

    def addItem(self):
        temp = classB('Тескт')
        self.L.append(temp)
        clone = classC(self,temp)
        return (clone)

a = A()
item1 = a.addItem()
print "------------------"
print a.L
print "------------------"
del item1
print "------------------"
print a.L
print "------------------"

Автор: DrDred 15.1.2007, 19:08
Цитата(yesint @  15.1.2007,  12:35 Найти цитируемый пост)
Задача: нужно каким-то образом сделать так, что при удалении переменной item1 удалялась и ссылка из списка внутри экземпляра а т.е. чтобы сам объект физически удалялся.
Сколько не бился не нашел как это сделать. 
Возможно ли такое и как?


Решение разделяется на 2 части:
- сначала немного меняем метод addItem
Код

def addItem(self):
    temp = classB()
    temp.backlink = self
    self.L.append(temp)
    return temp


-- потом в classB переопределяем метод __del__
Код

def __del__(self):
    if (self.backlink != None): self.backlink.remove(self)

Автор: setq 15.1.2007, 22:41
Мне кажется, лучше воспользоваться модулем weakref

Автор: albertn 16.1.2007, 10:04
DrDred, Основная проблема в том, что метод __del__ запускается только после того, как все ссылки на этот объект будут уничтожены, а нужно, чтобы после удаления локальной (глобальной) переменной происходило удаление и из списка. А в твоем методе из списка она сама никогда не удалится.

Автор: DrDred 16.1.2007, 10:43
Цитата(albertn @  16.1.2007,  10:04 Найти цитируемый пост)
Основная проблема в том, что метод __del__ запускается только после того, как все ссылки на этот объект будут уничтожены, а нужно, чтобы после удаления локальной (глобальной) переменной происходило удаление и из списка. А в твоем методе из списка она сама никогда не удалится. 

Согласен. Просто данная задача в условиях GC практически нерешаема. Т.е. чтобы объект прибился бы GC, на него не должно быть ссылок, а чтобы на него не было ссылок, его нужно сначала удалить из листа. Замкнутый круг...
Либо, как уже подсказали выше, помещать в спиок не сам объект, а weakref на него... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)