Repository navigation
Expand file tree
/
Copy pathmonkey_patching_demo.py
More file actions
64 lines (53 loc) · 2.44 KB
/
Copy pathmonkey_patching_demo.py
File metadata and controls
64 lines (53 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import time
class ExternalAIModel:
"""
Simulates a 3rd-party library class that we cannot modify directly.
"""
def predict(self, input_data):
print(f" [ExternalModel] Processing '{input_data}'...")
# Imagine this is an expensive network call
time.sleep(1)
return f"Prediction for {input_data}"
def patched_predict(self, input_data):
"""
Our new function that will replace the original 'predict' method.
This demonstrates injecting custom logic (like logging or caching)
into an existing class at runtime.
"""
print(f" [PATCHED] Intercepted call with data: {input_data}")
# We can still call the original logic if we saved it elsewhere,
# but here we'll just return a faster mock result.
return f"FAST Prediction for {input_data}"
def demonstrate_monkey_patching():
print("Demonstrating Monkey Patching in Python:")
print("=" * 60)
# 1. Behavior BEFORE patching
print("\n1. Original Behavior:")
model = ExternalAIModel()
start = time.time()
result1 = model.predict("Query A")
print(f"Result: {result1} (Took {time.time() - start:.2f}s)")
# 2. Applying the Monkey Patch
# We replace the class's method with our standalone function at runtime.
print("\n2. Applying Monkey Patch (Changing ExternalAIModel.predict)...")
ExternalAIModel.predict = patched_predict
# 3. Behavior AFTER patching
print("\n3. Patched Behavior:")
start = time.time()
result2 = model.predict("Query B")
print(f"Result: {result2} (Took {time.time() - start:.2f}s)")
# 4. Patching built-in modules (Commonly used in testing/mocking)
print("\n4. Patching Module-level functions (Simulating 'time.sleep' skip):")
original_sleep = time.sleep
time.sleep = lambda x: print(f" [PATCH] Suppressed sleep for {x} seconds.")
start = time.perf_counter()
time.sleep(100) # This would normally take 100 seconds!
print(f"Execution continued immediately. Duration: {time.perf_counter() - start:.4f}s")
# Restore for safety
time.sleep = original_sleep
if __name__ == "__main__":
demonstrate_monkey_patching()
print("\nMonkey Patching is the technique of replacing or extending code")
print("at runtime without modifying the source. It is extremely powerful")
print("for unit testing (mocking) and fixing bugs in third-party libraries,")
print("but should be used sparingly as it can make debugging difficult.")