I have given arbitraly class A
with method m
and I would like to create decorator that can be added to new function f
and this decorator will allow to execute f
every time that m
is called but to execute f
before m
and f
should intercept arguments of m
I need help defining pre_execution
decorator - I have something but it's not working and I can't figure out how to make it work
#a.py
class A:
def m(self, x):
return x+1
#mydecorator.py -- need help with code in this file
def pre_execution(klass, method):
old_fn = getattr(klass, method)
def inner(fn, *args):
# @wraps(fn)
def iin(*args, **kwargs):
fn(*args, **kwargs)
return old_fn(*args, **kwargs)
return iin
setattr(klass, method, inner)
return inner
# main.py
from a import A
from mydecorator import pre_execution
if __name__ == "__main__":
@pre_execution(A, 'm')
def f(*args, **kwargs):
print "in"
print "my code using args and kwargs"
print "out"
a = A()
print a.m(1) == 2
print a.m(1)
expected output:
in
my code using args and kwargs
out
True
I think what you want is
def pre_execution(klass, method):
old_method = getattr(klass, method)
def patch_klass(f):
def new_method(*args, **kwargs):
f(*args, **kwargs)
return old_method(*args, **kwargs)
setattr(klass, method, new_method)
return f
return patch_klass
pre_execution
saves a reference to the original method, then defines a function that will be returned and called on f
. This function defines a new method that calls f
before calling the original method. patch_klass
then replaces the old method with the new in. It also returns the original function unmodified, in case you want to use f
elsewhere.
$ python tmp.py
in
my code using args and kwargs
out
True
in
my code using args and kwargs
out
2
Note that this works in Python 2 or 3.