问题描述
我已经给 A
提供了任意的类 m
,我想创建可以添加到新函数 f
的装饰器,并且这个装饰器将允许执行 {{1} } 每次调用 f
但在 m
和 f
之前执行 m
应该拦截 f
我需要帮助定义 m
装饰器 - 我有一些东西但它不起作用,我不知道如何使它起作用
pre_execution
#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)
解决方法
我认为你想要的是
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
保存对原始方法的引用,然后定义将在 f
上返回和调用的函数。此函数定义了一个 new 方法,该方法在调用原始方法之前调用 f
。 patch_klass
然后用新的 in 替换旧方法。它还返回未修改的原始函数,以防您想在其他地方使用 f
。
$ python tmp.py
in
my code using args and kwargs
out
True
in
my code using args and kwargs
out
2
请注意,这适用于 Python 2 或 3。