Nerd For Tech
Published in

Nerd For Tech

weakref module in Python

Photo by Milad Fakurian on Unsplash

Been a while, two months and two weeks to be exact, since I wrote the last article. Without further ado, I am writing about module in Python. Let’s dive in.

The module allows Python programmer to create weak reference to objects. A weak reference is a reference that does not protect the object from getting garbage collected.

As we know, Python uses reference counting mechanism for garbage collection and reference count is increased when there is a strong reference. Let’s see an example:

On running the file , the output is:

Reference count for yobj: 1
Reference count of w_yobj is 1
Reference count for yobj: 2

We see that the reference count is increased only when there is strong reference as in line number .

We can extend more on this program to delete the objects with strong reference and see the decrease in the reference count. After the cleanup of the objects if we call the weakly referenced object it will return .

Output is:

Reference count for yobj: 1
Reference count of w_yobj: 1
Reference count for yobj: 2
Cleaning...After deleting yobj_2, reference count for yobj: 1calling weakref object, w_yobj, after deleting both objects...
Weak ref: None

Why is weakref used for? Very good question. It is used for

  1. In caching or mapping where the objects you are holding are expensive and you don’t want them to be alive just because it is in the mapping or caching.

2. To make life easier to deal with circular references.

Let’s see an example for mapping:

On running the file, the output is:

cache type: <class 'dict'>
reference count after initialization gem opal: 1
reference count after caching gem opal: 2
reference count after appending to list gem opal: 3
reference count after initialization gem ruby: 1
reference count after caching gem ruby: 2
reference count after appending to list gem ruby: 3
reference count after initialization gem fluorite: 1
reference count after caching gem fluorite: 2
reference count after appending to list gem fluorite: 3
List length: 3, contents: [PriceyObject(opal), PriceyObject(ruby), PriceyObject(fluorite)]cleaning list...After cleaning list, cache contains: dict_keys(['opal', 'ruby', 'fluorite'])opal=PriceyObject(opal)
ruby=PriceyObject(ruby)
fluorite=PriceyObject(fluorite)
demo returningDeleting PriceyObject(opal)
Deleting PriceyObject(ruby)
Deleting PriceyObject(fluorite)
cache type: <class 'weakref.WeakValueDictionary'>
reference count after initialization gem opal: 1
reference count after caching gem opal: 1
reference count after appending to list gem opal: 2
reference count after initialization gem ruby: 1
reference count after caching gem ruby: 1
reference count after appending to list gem ruby: 2
reference count after initialization gem fluorite: 1
reference count after caching gem fluorite: 1
reference count after appending to list gem fluorite: 2
List length: 3, contents: [PriceyObject(opal), PriceyObject(ruby), PriceyObject(fluorite)]cleaning list...Deleting PriceyObject(fluorite)
Deleting PriceyObject(ruby)
Deleting PriceyObject(opal)
After cleaning, cache contains: <generator object WeakValueDictionary.keys at 0x7f8a700addd0>demo returning

The difference between standard and module’s is that on deleting list containing strongly reference gem objects, does not contain the references to the gems object. While standard dictionary still has references and is able to iterate over them.

Now let’s come to an example of dealing with circular reference.

I am pulling an example from the memory management article which is about symmetric cousin relationship, here the cat’s genealogy.

The output is:

servy's refcount: 2
whiky's refcount: 2
AFTER DELETION OF servy
whiky's refcount: 2
AFTER ASSIGNING whiky's cousin to be None
whiky's refcount: 1

We saw circular reference which cause memory leaks by seeing reference count of object still being 2 after deletion of object. We overcame this circular reference by manually setting ‘s cousin to be .

We can deal with this type of relationship by using weak reference.

Output of the file is:

servy's refcount: 1
whiky's refcount: 1
AFTER DELETION OF servywhiky's refcount: 1
whiky's cousin: None

We see that reference count does not increase by setting value of attribute and when object is deleted 's attribute’s value is .

Wasn’t that easy peasy?!

In conclusion, module provides ways to refer to objects without additional huge memory need.

Do explore the official documentation to see all methods.

Thank you for reading. I’ll see you soon. ✨

Inspiration:

You can support me on Patreon!

--

--

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store