Monkey Patching in Python (Dynamic Behavior)
Last Updated :
22 Aug, 2025
In Python, Monkey Patching refers to dynamically modifying or extending behavior of a class or module at runtime. This allows developers to change how functions, methods or classes behave without altering original source code.
Monkey patching is a powerful feature, but it should be used carefully because it can lead to unexpected behavior if not managed properly.
For Example: Suppose we have a module monk.py with a simple class:
Python
# monk.py
class A:
def func(self):
print("func() is being called")
Normally, calling func() would output:
func() is being called
For changing behavior at runtime we can replace func() method dynamically by assigning a new function to it:
Python
import monk
# New function to replace original func()
def monkey_f(self):
print("monkey_f() is being called")
# Replacing the address of "func" with "monkey_f"
monk.A.func = monkey_f
obj = monk.A()
obj.func()
Output
monkey_f() is being called
Explanation:
- A new function monkey_f is defined.
- monkey_f is assigned to monk.A.func.
- All instances of class A now call monkey_f() instead of original func().
- This demonstrates Python’s ability to modify behavior dynamically at runtime.
Why Use Monkey Patching?
Monkey patching is useful in several scenarios:
- Fixing Bugs in Third-Party Modules: Methods can be patched without modifying original library.
- Testing and Mocking: Methods can be replaced during unit testing to simulate specific behaviors.
- Dynamic Behavior in Frameworks: Some frameworks, such as Django, use monkey patching internally to extend classes dynamically.
Selective Monkey Patching: Instance vs. Class
Monkey patching allows modifying the behavior of classes or their instances at runtime.
Example 1: This example shows how to patch a method for a single instance without affecting other instances of same class.
Python
class B:
def greet(self):
print("Hello from B!")
# Create instances
b1 = B()
b2 = B()
# Define new method
def new_greet(self):
print("Hello from monkey patch!")
# Patch only b1
b1.greet = new_greet.__get__(b1) # Bind method to instance
b1.greet()
b2.greet()
OutputHello from monkey patch!
Hello from B!
Explanation:
- class B defines method greet and instances b1 and b2 are created.
- New function new_greet is defined and bound only to b1 using __get__.
- Calling b1.greet() executes patched method.
- Calling b2.greet() executes original method, demonstrating selective patching.
Example 2: This example shows how to patch square() for one instance so it acts as a cube calculator, while other instances keep original method.
Python
class MathOps:
def square(self, x):
return x * x
# Create two instances
m1 = MathOps()
m2 = MathOps()
# Define a new method
def cube(self, x):
return x * x * x
# Patch only m1
m1.square = cube.__get__(m1) # Replace square with cube for m1
print(m1.square(3)) # Patched version → cube
print(m2.square(3)) # Original version → square
Explanation:
- MathOps.square() normally returns square of a number.
- Two instances is created m1 and m2 and new method cube() is defined.
- Only m1 is patched, so m1.square(3) now returns cube (27).
- m2 keeps original behavior and returns square (9).
Note: Monkey patching can break other code and make maintenance difficult. Use it cautiously mainly for testing, quick fixes or prototyping.
Explore
Python Fundamentals
Python Data Structures
Advanced Python
Data Science with Python
Web Development with Python
Python Practice