Hi, I would like to monkey patch a function 'decode' that is defined inside a class. It is defined there because it is a logical place, next to its counterpart *method* 'encode'. I can successfully monkey patch meth1, but when I call meth2, it does not use the patched decorator. How can this be done? In this example, I would like to effectively "turn off" @decode. I am hoping for a solution that works on Python 2.7 and 3.3+.
import inspect, functools class Foo(object): def decode(func): @functools.wraps(func) def wrapped(*args, **kwargs): print "original decorator was called" return func(*args, **kwargs).decode("utf-8") return wrapped def encode(self): """this is just here to show why decode() is defined within Foo""" pass def meth1(self): return "original method was called" @decode def meth2(self): return b"python rocks" # ---- works ----- f = Foo() print f.meth1() Foo.meth1 = lambda self: "new method was called" print f.meth1() print "-------------------" # ---- does not work ----- def patched_decode(func): @functools.wraps(func) def wrapped(*args, **kwargs): print "patched decorator was called" return func(*args, **kwargs) return wrapped f = Foo() print 'ORIGINAL' print inspect.getsource(Foo.decode) # shows source code of regular decode (as expected) result = f.meth2() print repr(result), type(result) #setattr(Foo, "decode", patched_decode) Foo.decode = patched_decode print 'PATCHED' print inspect.getsource(f.decode) # shows source code of patched_decode (as expected) result = f.meth2() print repr(result), type(result) # not patched at all! it's still unicode! ##### output: In [1]: %run monkey_patch.py original method was called new method was called ------------------- ORIGINAL def decode(func): @functools.wraps(func) def wrapped(*args, **kwargs): print "original decorator was called" return func(*args, **kwargs).decode("utf-8") return wrapped original decorator was called u'python rocks' <type 'unicode'> PATCHED def patched_decode(func): @functools.wraps(func) def wrapped(*args, **kwargs): print "patched decorator was called" return func(*args, **kwargs) return wrapped original decorator was called u'python rocks' <type 'unicode'> Regards, Albert-Jan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor