Monkey patching is a powerful โ€” but sometimes risky โ€” feature in Python that allows you to modify or extend the behavior of libraries, modules, or classes at runtime, without changing their source code.

Letโ€™s break it down clearly ๐Ÿ‘‡


๐Ÿ”น 1. Definition

Monkey patching means dynamically changing or extending code (like methods, functions, or classes) while a program is running.

In other words:

  • You “patch” (modify) an existing class or module.
  • You donโ€™t edit the original source file.
  • The changes apply immediately at runtime.

๐Ÿงฉ Example (Simple Explanation)

Letโ€™s say you have a built-in class or library method you want to change temporarily.

class Dog:
    def bark(self):
        return "Woof!"

Normally:

dog = Dog()
print(dog.bark())

Output:

Woof!

Now, you can monkey patch this class by redefining its method at runtime:

def new_bark(self):
    return "Meow!"  # ๐Ÿฑ A dog meowing? Monkey patched!

Dog.bark = new_bark  # Monkey patch applied

dog = Dog()
print(dog.bark())

Output:

Meow!

โœ… Youโ€™ve successfully changed the behavior of the Dog class without modifying its source code.

Thatโ€™s monkey patching.


๐Ÿ”น 2. Where Itโ€™s Commonly Used

Monkey patching is often used when:

  1. You want to fix a bug or add functionality in a third-party library.
  2. You need to mock or override behavior for testing.
  3. You want to temporarily inject custom behavior (e.g., logging, debugging).

๐Ÿ”น 3. Example: Patching a Built-in Library Function

Letโ€™s patch Pythonโ€™s built-in time.sleep() function so it doesnโ€™t actually wait.

import time

def fast_sleep(seconds):
    print(f"Skipping sleep for {seconds} seconds")

# Monkey patch time.sleep
time.sleep = fast_sleep

print("Start")
time.sleep(5)
print("End")

Output:

Start
Skipping sleep for 5 seconds
End

โœ… You replaced time.sleep() with your own function at runtime โ€” no waiting time!


๐Ÿ”น 4. Example: Monkey Patching for Unit Testing

Monkey patching is commonly used in testing to simulate dependencies or isolate functions.

Example: Patch a function that makes an API call to avoid real network requests.

# app.py
import requests

def get_user():
    response = requests.get("https://api.example.com/user")
    return response.status_code

โœ… Test with Monkey Patching

# test_app.py
import app

def mock_get(url):
    class MockResponse:
        status_code = 200
    return MockResponse()

# Monkey patch requests.get
import requests
requests.get = mock_get

print(app.get_user())  # Should print 200 (mocked)

Output:

200

โœ… No real HTTP request was made โ€” we patched requests.get() with a fake version.


๐Ÿ”น 5. Example: Monkey Patching a Method in a Module

Letโ€™s say we have a math library that multiplies two numbers, but we want to force it to add instead.

import math

def fake_multiply(x, y):
    return x + y

math.prod = fake_multiply  # Monkey patch math.prod

print(math.prod([2, 3]))  # Using patched version

Output:

5

โœ… We changed the behavior of a standard library method on the fly.


๐Ÿ”น 6. Monkey Patching vs Normal Overriding

FeatureMonkey PatchingOverriding (Subclassing)
When DoneAt runtime (dynamically)At definition time
Source Code Modified?โŒ Noโœ… Yes (in subclass)
Affects Original Class?โœ… YesโŒ No (affects only subclass)
SafetyRisky (may cause side effects)Safe and explicit
Use CasePatching 3rd-party code temporarilyExtending own classes

โœ… Monkey patching directly modifies the original class or module.


๐Ÿ”น 7. Caution โ€” When Not to Use Monkey Patching

Monkey patching can be dangerous if not handled carefully.

โš ๏ธ Drawbacks:

  1. โŒ Can make code unpredictable or hard to debug.
  2. โŒ Updates to the original library may break your patch.
  3. โŒ Difficult for new developers to understand whatโ€™s happening.
  4. โŒ Can lead to naming conflicts or infinite loops if done incorrectly.

โœ… Use it only when:

  • You canโ€™t modify the original code (e.g., external library).
  • Youโ€™re writing temporary patches or tests.

๐Ÿ”น 8. Example: Safe Monkey Patching with Context

You can use context managers to apply a monkey patch temporarily.

import time
from unittest.mock import patch

def custom_sleep(seconds):
    print(f"Fake sleep for {seconds} seconds")

print("Before patching:")
time.sleep(2)

with patch("time.sleep", custom_sleep):
    print("\nInside patch:")
    time.sleep(5)

print("\nAfter patching:")
time.sleep(2)

Output:

Before patching:
(Waits 2 seconds)

Inside patch:
Fake sleep for 5 seconds

After patching:
(Waits 2 seconds)

โœ… unittest.mock.patch() allows temporary monkey patching, automatically restoring the original behavior.


๐Ÿ”น 9. Real-World Example โ€” Flask / Django

Many frameworks like Flask, Django, and gevent use monkey patching internally.

Example:

from gevent import monkey
monkey.patch_all()

โœ… This replaces Pythonโ€™s standard libraries (socket, thread, etc.) with non-blocking versions, enabling asynchronous I/O without modifying your code.


๐Ÿงพ Summary Table

FeatureMonkey Patching
DefinitionModifying or extending code at runtime without changing the source
How It WorksReassign or replace methods/functions dynamically
When UsedTo fix bugs, add temporary behavior, or for testing
Common Use CasesMocking API calls, debugging, patching 3rd-party libraries
RiskCan break code if library updates or if used carelessly
Safer AlternativeSubclassing or using unittest.mock.patch()

โœ… In short:

Monkey patching is the practice of dynamically modifying a module or class at runtime โ€”
often used for testing, debugging, or fixing behavior without touching the original source code.


๐Ÿงฉ Final Example (Quick Recap)

class Car:
    def drive(self):
        return "Driving normally"

def turbo_drive(self):
    return "Driving at turbo speed!"

Car.drive = turbo_drive  # ๐Ÿ’ Monkey patch

car = Car()
print(car.drive())

Output:

Driving at turbo speed!

โœ… The method drive() was replaced at runtime โ€”
and thatโ€™s exactly what Monkey Patching means in Python.


Scroll to Top