Найти - Пользователи
Полная версия: gc и циклические ссылки
Начало » Python для новичков » gc и циклические ссылки
1
comm
Не могу самостоятельно разобраться:
class Father():
children=[]
def __del__(self):
print u'Father умер'

class Child():
father=None
def __init__(self,f):
self.father = f
def __del__(self):
print u'Child умер'

f=Father()
c=Child(f)

f.children.append(c)

f=c=1
print u'Все умерли'
результат:
>>>Все умерли

То есть деструкторы не вызывались, смотрим мусор:
import gc
gc.garbage
результат
>>>

На сколько я правильно понимаю, gc не должен обрабатывать объекты с определенным деструктором, таким образом, тогда почему он не поместил их в gc?
Что на самом деле произошло с f и c?
Андрей Светлов
Вы child кладете в класс Father, на нужно - в экземпляр
# -*- coding: utf-8 -*-
import gc
#gc.set_debug(gc.DEBUG_LEAK)

class Father():
def __init__(self):
self.children=[]

def __del__(self):
print u'Father умер'

class Child():
father=None
def __init__(self,f):
self.father = f

def __del__(self):
print u'Child умер'

f=Father()
c=Child(f)

f.children.append(c)

print u'Все умерли'

del f, c

print gc.collect()

print u'Мусор'
print gc.garbage
comm
Андрей Светлов спасибо ! Теперь все встало на свои места!
Однако у меня новый вопрос, как принято в питоне, “правильно”(python way и тд.) работать с циклическими ссылками, я нашел 3и варианта:
1 забить на них и предоставить это дело gc(не использовать __del__)
2 вручную разрывать ссылки после использования объекта
3 использовать слабые ссылки (weakref)?
Андрей Светлов
1. Забить - проще всего. Зачастую - срабатывает.
2. Иногда мне нужно, чтобы объекты уничтожались сразу же после того, как станут не нужны. Тогда - слабые ссылки. __del__ опять же работает, или callback в weakref.ref можно задавать. В общем, дешево и сердито. Правило очень простое: если получается без лишних затрат не доводить дело до garbage collector - возможно, это хорошая идея.
3. Вручную разрывать не нужно никогда - потому что рано или поздно забудете и ошибетесь. Утечки памяти довольно тяжело находятся (guppy.pe в помощь).
Пожалуй, я знаю только одно исключение - context managers, в которых __exit__ вызывается автоматически.
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