What Are Duck Typing and Monkey Patching in Python?

One reason why we say Python is flexible

Yong Cui, Ph.D.
Jun 19 · 5 min read
Image for post
Image for post

This isn’t an article about animals, although it’s not too common to have three animal names in a headline. Today, I would like to discuss duck typing and monkey patching in Python. Both features are critical to making Python a flexible language to work with for general purposes.

After reading this article, I hope that you’ll have an intuitive idea about how duck typing and monkey patching work in Python. Let’s get started!


Duck Typing

The term duck typing isn’t something new to many programmers — especially if you have some background in dynamic programming languages. However, it was not invented by computer scientists. Let’s see its general definition:

“If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.” — Wikipedia

This is a form of abductive reasoning, and it means that we draw our conclusion of one’s identity only based on their external appearance and behaviors instead of their actual types. In programming languages, duck typing represents an implementation pattern of defining how particular objects behave without worrying about the types of the class. It may sound too abstract, but with a concrete example, you’ll find it not hard at all.

First, we’ll create a “true” duck class that we’ll use as a benchmark to define a duck’s behaviors. As shown below, the Duck class has two instance methods — swim() and quack() (two behaviors that you can expect with ducks):

As an instance object of the Duck class, we can verify that a duck is able to behave like a duck. It can swim and quack. As shown below, we first create the duck_testing function to check whether a presumed duck can swim and quack. As expected, the duck instance does just what it’s supposed to and passes the duck typing test:

Did you notice that I actually checked the type of the duck instance object using the introspection function isinstance? By verifying that the presumed duck is an instance of the Duck class, we are sure that it will pass the duck typing test. However, it’s tedious to check the object of interest’s type to expect its behavior, which is exactly what duck typing tries to avoid. The key to duck typing is that we don’t care about the object’s type. As long as it can swim and quack (or any other defined behaviors or methods), we consider it to be a duck (or any concerned type).

Let’s see how duck typing works beyond the Duck class that we’ve been talking about. For the sake of contrast, I’ll create two custom classes:

As shown above, the ToyDuck class has both the swim() and quack() methods implemented. Thus, according to duck typing, we should expect it to pass the duck typing test. On the other hand, the Human class only has the swim() method and thus won’t pass the duck typing test to qualify as a duck. Let’s verify our predictions next:

As expected, a toy duck can swim and quack, while a human can only swim. The human instance object isn’t considered a duck-like object. Notably, neither the toy_duck nor the human objects are an instance object of the original Duck class. It’s just the supported behaviors (i.e. swim and quack) that make the toy_duck a duck-like object and pass the duck typing test. It’s the key to implementing duck typing.


Monkey Patching

The term monkey patching has a very interesting name. According to Wikipedia, the monkey patch is probably related to the earlier term “guerrilla patch,” which referred to changing code sneakily. Given guerrilla’s homophonous relationship with gorilla and gorilla’s relationship with monkey (both being primates), the monkey patch was engendered. In terms of its specific conceptualization in the world of programming, it’s defined as such:

“A monkey patch is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program).” — Wikipedia

As a dynamic language, Python allows us to use monkey patching in our coding by extending specific modules or classes without modifying their original implementations. In this section, we want to make instances of the Human class (defined above) able to behave like a duck. I know it’s weird, but just think about Donald Duck as a human.

To understand how monkey patching works mechanistically, let’s step back and see how Python classes work. As we all know, Python is an object-oriented language that operates by treating everything as objects, including modules and classes. To provide a proof of concept, we’ll just apply monkey patching to a custom class. Before we dive into the details, let’s see a simplified Python class:

It’s definitely not a fancy class, with just a class attribute and an instance method (if you don’t know about the self argument, check out this article). One thing to note is that we can access Foo’s __dict__ attribute, which lists all the attributes of this class, including the attr1 and bar. As mentioned previously, Python classes are also objects, which means that we can dynamically update their attributes even during the runtime. By the way, that’s exactly what monkey patching is all about.

As you can see in the code snippet above, we directly set one attribute and one function to the class object. As a result, the updated class’ __dict__ attribute reveals that attr2 and bar2 are indeed “patched” to the original class. Importantly, we can access attr2 as we normally do with the predefined attributes (e.g. attr1).

Now that we know how monkey patching works with a generic class, let’s try it with the Human class. Just a friendly reminder: The desired feature is to make a human object quack so that it can pass the duck typing test. Importantly, we’re not going to change the original class. As shown below, we define a function named quack and set this function as the quack attribute of the Human class:

One thing to note is that the defined quack function has an argument that doesn’t seem to be used, but it’s essential to have it. Because the quack function is an instance method, which will always have an argument (we used self in this class, but you can call it whatever you want) referring to the instance object. If you’re still confused about the self argument, please check out my previous articles.

As you can see, after the monkey patching, the instance object of the Human class is successfully able to pass the duck typing test. Again, this pass doesn’t involve changing the implementation of the original Human class. Instead, we “patch” these features outside of the class. That’s the beauty of this dynamic feature.


Recap

In this article, we reviewed how duck typing and monkey patching work in Python. Here’s a quick recap of these two terms:

  • Duck typing is a means to design a class to have the desired behaviors without subclassing or implementing a protocol, interface, or abstract base classes. It’s OK if you don’t know these terms. You can still use duck typing. Again, the key is to implement the required methods and attributes for the desired behaviors.
  • Monkey patching is an extension mechanism that allows us to implement additional features of existing modules and classes without modifying the original implementations. However, use it with caution because different parts of your code that patch the same module/class will result in unexpected behaviors by stepping on each other’s toes.

Better Programming

Advice for programmers.

Thanks to Zack Shapiro

Yong Cui, Ph.D.

Written by

Work at the nexus of biomedicine, data science & mobile dev. Love to write on these technological topics. Follow me @ycui01 on Twitter to get latest articles.

Better Programming

Advice for programmers.

Yong Cui, Ph.D.

Written by

Work at the nexus of biomedicine, data science & mobile dev. Love to write on these technological topics. Follow me @ycui01 on Twitter to get latest articles.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

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