Weak References in Python - GeeksforGeeks

27 Apr, 2022
Python’s memory management algorithm uses a reference counting mechanism for garbage collection, which tracks all reachable objects. All Python objects include a reference count field, which counts how many objects are referencing it. If an object is referenced by another object, then its counter is set to a non-zero number and the object can’t be garbage collected. If the counter reaches zero, the garbage collector will free that object. 
Below is a short example of how can we find the reference count of any object in python.
Python3
import ctypes # list object which is referenced by# my_listmy_list = [1, 2, 3] # finding the id of list objectmy_list_address = id(my_list) # finds reference count of my_listref_count = ctypes.c_long.from_address(my_list_address).value print(f"Reference count for my_list is: {ref_count}")
Output:
Reference count for my_list is: 1
So, now as we are clear with the basics of references and garbage collections let’s move to what are weak references and why do we need them?
Unlike the references we discussed above, a weak reference is a reference that does not protect the object from getting garbage collected. Why do we want such a thing in the first place?
There are two main applications of weak references:
Implement caches for large objects (weak dictionaries).
Reduction of Pain from circular references.
To create weak references, Python has provided us with a module named weakref. A point to keep in mind before using weakref is that some builtins such as tuple or int do not support this. list and dict support is either but we can add support through subclassing. Let’s discuss the applications in detail.
Sometimes a large object is stored in the cache so there is no need to keep it alive. Let’s you have a large number of image objects and they are being used as keys to map to images due to which these objects will be kept alive. 
Fortunately, weakref module provides something called as WeakKeyDictionary and WeakValueDictionary doesn’t keep the objects alive as they appear in the mapping objects.
The following classes and methods are provided by weakref module:
class weakref.ref(object[, callback])  – This returns a weak reference to the object.
weakref.proxy(object[, callback]) – This returns a proxy to object which uses a weak reference.
weakref.getweakrefcount(object) – Return the number of weak references and proxies which refer to object.
weakref.getweakrefs(object) – Return a list of all weak reference and proxy objects which refer to object.
Let’s understand the work with some examples:
Example 1: 
In the below-given example, we create a normal list object, a weak reference list object, and a proxy list object and print the weak reference count for all of them.
Python3
# importing weakref moduleimport weakref # creating a classclass GFG(list):    pass # creating object of a classobj = GFG("Geeks") # creating a normal list objectnormal_list = objprint(f"This is a normal object: {normal_list}") # this returns a weak reference to objweak_list = weakref.ref(obj)weak_list_obj = weak_list()print(f"This is a object created using weak reference: {weak_list_obj}") # creating a proxy of original objectproxy_list = weakref.proxy(obj)print(f"This is a proxy object: {proxy_list}") # printing the count of weak referencesfor objects in [normal_list, weak_list_obj, proxy_list]:    print(f"Number of weak references: {weakref.getweakrefcount(objects)}")
Output:
This is a normal object: [‘G’, ‘e’, ‘e’, ‘k’, ‘s’] This is a object created using weak reference: [‘G’, ‘e’, ‘e’, ‘k’, ‘s’] This is a proxy object: [‘G’, ‘e’, ‘e’, ‘k’, ‘s’] Number of weak references: 2 Number of weak references: 2 Number of weak references: 0
As the normal object has references to the weak reference object hence both of them have a weak reference count of 2 but as proxy_object is a proxy created from the weak reference thus it does not have a reference count.
Example 2:
In this example, we will see how to use WeakValueDictionary which we discussed earlier in the article.
Python3
# import weakref moduleimport weakref # creates a classclass GFG:     def __init__(self,data):        self.data = data         def __repr__(self):        return str(self.data) # creates an object of class GFG# (consider that this object is very# large and has been stored in the cache)value = GFG(5) # creates a Weak Value Dictionaryweak_dict = weakref.WeakValueDictionary() # inserting value into the dictionaryweak_dict["num"] = value # getting the weak ref countprint(f'Weak reference count is: {weakref.getweakrefcount(weak_dict)}') # deleting the weak dictionarydel weak_dict # running this will generate error# print(weak_dict)
 Output:
Weak reference count is: 1
In the above example, we assumed that there is a really large object which has been placed in the cache so we have created a weak ref dictionary to store that key and value pair so it will be garbage collected.
 
mmmarcelino96
python-basics
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Install PIP on Windows ?
Check if element exists in list in Python
How To Convert Python Dictionary To JSON?
How to drop one or multiple columns in Pandas Dataframe
Python Classes and Objects
Python | Get unique values from a list
Python | os.path.join() method
Defaultdict in Python
Create a directory in Python
Python | Pandas dataframe.groupby()