Many times it can happen that you are using a library and want to modify some of the functionality provided by the library. The best way for this would be to extend the class and override the functionality with your own implementation. Additionally, there is another quick and easy way of achieving the same using monkey patching.

In this blog, I will show how to use monkey patching. As a disclaimer, I must mention that monkey patching is not a recommended way of overriding method (or attributes) as it is confusing for others when reading the code and can be difficult to debug. The main purpose I used monkey patching  is mainly for prototyping, to check if a new implementation is better than what is currently in place. Having warned you, below is a example of monkey patching.

Lets say I have imported a data cleaner class which provides a bunch  of functions for cleaning text including one below which removes stop words and stems the words.

from nltk.corpus import stopwords
from nltk import word_tokenize
from nltk.stem.porter import PorterStemmer
class Cleaner():
    def stop_and_stem (text, stemmer=PorterStemmer()):
        stoplist = stopwords.words("english")
text_stemmed = [stemmer.stem(word) for word in word_tokenize(text) if word not in stoplist]
text = ' '.join(text_stemmed)
return text

My implementation where I am using this cleaner will be something like:

from cleaner import Cleaner

cleaner = Cleaner()
text = cleaner.stop_and_stem(text)

If, i want to quickly try a slightly different implementation of stop_and_stem, for example ignore all words less than 3 characters long without having to modify my implementation. I can define a new function and do something like

def new_stop_and_stem (text, stemmer=PorterStemmer()):
     """ Removes stop words and stems """
     stoplist = stopwords.words("english")
     text_stemmed = [stemmer.stem(word) for word in word_tokenize(text) if word not in stoplist and len(word) > 3]
     text = ' '.join(text_stemmed)
     return text

cleaner.stop_and_stem = new_stop_and_stem
text = cleaner.stop_and_stem(text)

This way, I can replace the function without having to change the usage or the definition of the class and test new ideas. This can be very handy when prototyping new ideas on existing implementation without touching  any working code.

There is another use case for monkey patching when doing unit testing, I will introduce it in my next blog.

Hope you found this useful.

If you have any questions or suggestions for future blogs, please do drop a line in the comments section.