Weak List References¶
A standard list
object stores every internal object as a direct reference.
That is, if the list
exists, then its internally stored objects exist.
A WeakList
instance is the exact same as a python list
, except that it
only stores weak references (using weakref.ref()
) of the objects. All access
(add/delete/comparison/slicing) is still the same as native list
, done with
the actual objects. This gives it a specific behavior where if an object it
references is no longer alive (eg, cleaned up by gc
), it is cleaned up and
removed from the WeakList
.
# Example
# -------
#
# WeakList use case
from pyats.datastructures import WeakList
# create a class for demo (base object cannot be weakref'ed)
class NewObject(object):
pass
# create a couple instances
a = NewObject()
b = NewObject()
c = NewObject()
# create a list and its weaklist
l = [a, b, c]
# [<NewObject object at 0xf76d65ec>,
# <NewObject object at 0xf76d664c>,
# <NewObject object at 0xf76d654c>]
wl = WeakList(l)
# WeakList([<NewObject object at 0xf76d65ec>,
# <NewObject object at 0xf76d664c>,
# <NewObject object at 0xf76d654c>])
# comparison between a weaklist and a list is the exact same
l == wl
# True
# access also yields the same, normal objects
wl[0]
# <NewObject object at 0xf76d65ec>
wc[0] is l[0]
# True
# removing the actual objects (ref counter = 0)
# removes the object from weaklist
# (deleting l as well so that no references to a exists)
del a
del l
# note now that wl only has 2 items left (b and c)
wl
# WeakList([<NewObject object at 0xf76d664c>,
# <NewObject object at 0xf76d654c>])
Tip
this can be extremely useful when you need to build a list of something without incrementing its reference counters.
Note
you can mimic this entire behavior by creating a list and add only weakref objects to it. This just eliminates that overhead.
Creation¶
Create a WeakList
the same way as creating your typical list
objects by
providing the constructor any iterable.
# Example
# -------
#
# WeakList creation
from pyats.datastructures import WeakList
# assuming we had a list of objects called 'l'
# create using another list
wl = WeakList(l)
# create using an iterable
wl = WeakList(iter(l))
Access¶
All list
usage patterns & APIs work also on WeakList
. From a usability
perspective, all access appears as if you are dealing with a standard list
object, except that the internally stored references are weak references.
# Example
# -------
#
# WeakList access
# assuming we had a list of objects called 'l'
# create using another list
wl = WeakList(l)
# everything is the same
wl[0] is l[0]
# True
wl == l
# True
wl[1:2] == l[1:2]
# True
Hint
essentially, the sole difference between a list
and WeakList
is how
reference to objects are stored internally. There are no external apparent
differences.
Limitations¶
The only requirement is that objects stored into a WeakList
must be able to
have its weak reference objects created by weakref.ref()
api. Eg, objects
such as str
and int
cannot have weak references, and thus cannot be
added to a WeakList