After monkey patching an instance method (using types.MethodType
) I pass the monkey patched object to a library which copies it (using copy.copy
) and calls the monkey patched method. The monkey patched method gets called successfully but the self
parameter references to the old (not copied object).
import copy
import types
class Person:
def __init__(self, lang):
self.lang = lang
def hello(self, n):
print(id(self), f"{n} times hello in {self.lang}")
def mean_hello(self, n):
print(id(self), f"{n} times mean hello in {self.lang}")
a = Person('English')
b = copy.copy(a)
b.lang = "French"
print(id(a), id(b)) # 139885310130440 139885310130720
a.hello(1) # 139885310130440 1 times hello in English
b.hello(1) # 139885310130720 1 times hello in French
a.hello = types.MethodType(mean_hello, a)
c = copy.copy(a)
c.lang = 'German'
print(id(a), id(c)) # 139885310130440 139885310130664
a.hello(2) # 139885310130440 2 times mean hello in English
c.hello(2) # 139885310130440 2 times mean hello in English
From the example it can be seen that the last line c.hello(2)
calls the monkey patched method with self
referencing to a
. Why does this happen? Is there a way to avoid this?