Общее удаление объекта в python - PullRequest
1 голос
/ 13 марта 2011

Есть ли способ гарантировать, что когда объект удаляется, он полностью удаляется из того места, где он есть?

Например, если вы сделали что-то вроде:

A = NewObject()
B = NewObject()
C = NewObject()

List1 = [A,B,C]
List2 = [1,2,3,C]

del A
del List2[3]

иудалить объекты, где бы они ни находились; это означает, что List1 будет содержать только B, а List2 будет содержать только 1,2,3.

Можно ли каким-либо образом добиться такого поведения?

Ответы [ 3 ]

4 голосов
/ 13 марта 2011

Вы можете использовать слабые ссылки в некоторых случаях. Если вам все равно, если C останется в живых в List2, вы можете заключить его в слабую ссылку, и когда ссылка на C истечет из List1, сборщик мусора соберет любую связанную с ним память.

Python использует подсчет ссылок, чтобы решить, следует ли собирать объект, поэтому пока ссылка хранится где-то, вы не можете полностью удалить этот объект. Однако, если слабая ссылка оборачивает объект, эта ссылка не учитывается. Так что, когда счет упадет до 0, он будет собран на удобство GC.

Убедитесь, что вы полностью прочитали документацию, так как есть немало предостережений, связанных со слабыми ссылками. Особенно типы объектов, которые могут быть использованы в пределах слабой ссылки.

Редактировать:

Пример -

>>> class List(list):
...     pass
... 
>>> weaklist = List()
>>> weaklist.append('a')
>>> weaklist.append('b')
>>> stronglist = [ ['c','d','e'] ]
>>> weaklist
['a', 'b']
>>> stronglist
[['c', 'd', 'e']]
>>> import weakref
>>> stronglist.append(weakref.ref(weaklist))
>>> stronglist
[['c', 'd', 'e'], <weakref at 0x10046e578; to 'List' at 0x100455f70>]
>>> stronglist[1]()
['a', 'b']
>>> del weaklist
>>> stronglist
[['c', 'd', 'e'], <weakref at 0x10046e578; dead>]
>>> stronglist[1]()
>>>

Я настоятельно рекомендую прочитать всю документацию по слабым местам. Похоже, вы хотите создать структуру узла, но иметь возможность ссылаться на эту структуру узла из менеджера. Вы должны создавать свои узлы как обычные объекты, но размещать слабые ссылки на эти объекты в диспетчере. Таким образом, когда узел удаляется, ссылка в менеджере просто умирает.

Кандидатом для этого будет WeakValueDictionary, определенный в модуле слабой связи.

2 голосов
/ 13 марта 2011

Нет. Вы удаляете имя , а не реальный объект. Не существует причины или механизма, позволяющего уничтожить объект (и другие имена), когда удаляется только одно имя.

1 голос
/ 13 марта 2011

Не пытайтесь сделать это, это не сработает. Структурируйте вашу программу так, чтобы объекты автоматически удалялись, когда они больше не нужны.

Может быть, вы хотите освободить некоторые внешние ресурсы, которые использует ваш объект. Не используйте удаление объекта для этого (__del__ не является деконструктором!) - вместо этого используйте протокол менеджера контекста (он же оператор with). Я не могу придумать другую причину, чтобы попробовать это ...

...