weakref — 对象的若引用
优质
小牛编辑
126浏览
2023-12-01
引用
# weakref_ref.py
import weakref
class ExpensiveObject:
def __del__(self):
print('(Deleting {})'.format(self))
obj = ExpensiveObject()
r = weakref.ref(obj)
print('obj:', obj)
print('ref:', r)
print('r():', r())
print('deleting obj')
del obj
print('r():', r())
引用回调
# weakref_ref_callback.py
import weakref
class ExpensiveObject:
def __del__(self):
print('(Deleting {})'.format(self))
def callback(reference):
"""Invoked when referenced object is deleted"""
print('callback({!r})'.format(reference))
obj = ExpensiveObject()
r = weakref.ref(obj, callback)
print('obj:', obj)
print('ref:', r)
print('r():', r())
print('deleting obj')
del obj
print('r():', r())
Finalizing Objects
# weakref_finalize.py
import weakref
class ExpensiveObject:
def __del__(self):
print('(Deleting {})'.format(self))
def on_finalize(*args):
print('on_finalize({!r})'.format(args))
obj = ExpensiveObject()
weakref.finalize(obj, on_finalize, 'extra argument')
del obj
# weakref_finalize_atexit.py
import sys
import weakref
class ExpensiveObject:
def __del__(self):
print('(Deleting {})'.format(self))
def on_finalize(*args):
print('on_finalize({!r})'.format(args))
obj = ExpensiveObject()
f = weakref.finalize(obj, on_finalize, 'extra argument')
f.atexit = bool(int(sys.argv[1]))
# weakref_finalize_reference.py
import gc
import weakref
class ExpensiveObject:
def __del__(self):
print('(Deleting {})'.format(self))
def on_finalize(*args):
print('on_finalize({!r})'.format(args))
obj = ExpensiveObject()
obj_id = id(obj)
f = weakref.finalize(obj, on_finalize, obj)
f.atexit = False
del obj
for o in gc.get_objects():
if id(o) == obj_id:
print('found uncollected object in gc')
# weakref_finalize_reference_method.py
import gc
import weakref
class ExpensiveObject:
def __del__(self):
print('(Deleting {})'.format(self))
def do_finalize(self):
print('do_finalize')
obj = ExpensiveObject()
obj_id = id(obj)
f = weakref.finalize(obj, obj.do_finalize)
f.atexit = False
del obj
for o in gc.get_objects():
if id(o) == obj_id:
print('found uncollected object in gc')
代理
# weakref_proxy.py
import weakref
class ExpensiveObject:
def __init__(self, name):
self.name = name
def __del__(self):
print('(Deleting {})'.format(self))
obj = ExpensiveObject('My Object')
r = weakref.ref(obj)
p = weakref.proxy(obj)
print('via obj:', obj.name)
print('via ref:', r().name)
print('via proxy:', p.name)
del obj
print('via proxy:', p.name)
缓存对象
# weakref_valuedict.py
import gc
from pprint import pprint
import weakref
gc.set_debug(gc.DEBUG_UNCOLLECTABLE)
class ExpensiveObject:
def __init__(self, name):
self.name = name
def __repr__(self):
return 'ExpensiveObject({})'.format(self.name)
def __del__(self):
print(' (Deleting {})'.format(self))
def demo(cache_factory):
# hold objects so any weak references
# are not removed immediately
all_refs = {}
# create the cache using the factory
print('CACHE TYPE:', cache_factory)
cache = cache_factory()
for name in ['one', 'two', 'three']:
o = ExpensiveObject(name)
cache[name] = o
all_refs[name] = o
del o # decref
print(' all_refs =', end=' ')
pprint(all_refs)
print('\n Before, cache contains:', list(cache.keys()))
for name, value in cache.items():
print(' {} = {}'.format(name, value))
del value # decref
# remove all references to the objects except the cache
print('\n Cleanup:')
del all_refs
gc.collect()
print('\n After, cache contains:', list(cache.keys()))
for name, value in cache.items():
print(' {} = {}'.format(name, value))
print(' demo returning')
return
demo(dict)
print()
demo(weakref.WeakValueDictionary)