Reputation: 3624
I am trying to learn python monkey patching. I have a simple example where I am trying to monkey patch just a single instance rather than the class itself.
My code:
# add.py
import types
class Math(object):
def __init__(self):
self.name = ''
def add(self, x, y, name):
self.name = name
print 'calling from ', self.name
return x + y
def monkey_patch(self):
add = self.add
def squared_sum(x, y):
return x**2 + y**2
add = types.MethodType(squared_sum, self)
if __name__ == '__main__':
math = Math()
print math.add(3, 4, 'before monkey_patching')
math.monkey_patch()
print math.add(3, 4, 'after monkey_patching')
Expected Output:
calling from before monkey_patching
7
calling from after monkey_patching
25
Generated Output:
calling from before monkey_patching
7
calling from after monkey_patching
7
Can someone point out where I am going wrong. And also how can I monkey patch the add method when I am doing it from a different file i.e. When I import Math class from add.py in a different file, how can I monkey patch it's add method.
Upvotes: 1
Views: 769
Reputation: 122024
Your code doesn't do what you think it does:
def monkey_patch(self):
add = self.add # add now points to self.add
def squared_sum(x, y):
return x**2 + y**2
add = types.MethodType(squared_sum, self) # add now points to squared_sum
# method ends, add and squared_sum are abandoned
This doesn't actually change self.add
. Also, squared_sum
doesn't take self
or name
arguments, unlike add
, and doesn't have the print
that add
does. To make this work fully, do:
def monkey_patch(self):
def squared_sum(self, x, y, name):
self.name = name
print 'calling from ', self.name
return x**2 + y**2
self.add = types.MethodType(squared_sum, self)
To patch outside the class definition:
math = Math()
def func(self, x, y, name):
return x ** y
math.add = types.MethodType(func, math)
Upvotes: 4