Я пытаюсь использовать weakref.finalize
для обработки уничтожения объектов в соответствии с https://docs.python.org/3.6/library/weakref.html#comparing-finalizers-with-del-methods
Однако объекты никогда не собираются сборщиком мусора Python, поэтому я не могу проверить, что я делаю.weakref.finalize
вызывается только после завершения скрипта (см. atexit
).
Но я не могу выяснить, какие блоки собирает мусор.См. Следующий пример:
import gc
from weakref import finalize, ref
import objgraph
def close_after_del(obj):
def _cleaner(obj_):
print("!object get's closed now")
obj_.close()
finalize(obj, _cleaner, obj)
print('open file')
fp = open('blub', 'w')
close_after_del(fp)
print('check for other references:')
objgraph.show_refs(fp)
print(gc.get_referrers(fp))
print('delete and collect it')
w_fp = ref(fp)
del fp
gc.collect()
print('check references again:')
print(gc.get_referrers(w_fp) if w_fp() is not None else "Weak reference is gone")
print("should be deleted by now but isn't")
objgraph.show_refs(w_fp)
objgraph
показывает только слабые ссылки, которые не должны иметь значения (я только добавил его позже, чтобы проверить ссылки).gc.get_referrers
показывает словарь, это связано с globals
или locals
?
Решение в соответствии с ответом @ user2357112:
from weakref import finalize
def close_after_del(proxy, fp):
def _cleaner():
print("!object gets closed now!")
fp.close()
finalize(proxy, _cleaner)
class Proxy():
def __init__(self, fp):
self.fp = fp
print('open file')
proxy = Proxy(open('blub', 'w'))
close_after_del(proxy, proxy.fp)
print('delete and collect it')
del proxy
import gc; gc.collect()
print("Got collected!")