我正在将类A(我从其他人导入,因此我无法修改它)实例化到我的类X.
有没有办法可以拦截或包装对A中方法的调用?即,在下面的代码中我可以打电话
x.a.p1()
并获得输出
X.pre A.p1 X.post
很多TIA!
class A: # in my real application, this is an imported class # that I cannot modify def p1(self): print 'A.p1' class X: def __init__(self): self.a=A() def pre(self): print 'X.pre' def post(self): print 'X.post' x=X() x.a.p1()
Thomas Watne.. 6
以下是我和我的同事提出的解决方案:
from types import MethodType class PrePostCaller: def __init__(self, other): self.other = other def pre(self): print 'pre' def post(self): print 'post' def __getattr__(self, name): if hasattr(self.other, name): func = getattr(self.other, name) return lambda *args, **kwargs: self._wrap(func, args, kwargs) raise AttributeError(name) def _wrap(self, func, args, kwargs): self.pre() if type(func) == MethodType: result = func( *args, **kwargs) else: result = func(self.other, *args, **kwargs) self.post() return result #Examples of use class Foo: def stuff(self): print 'stuff' a = PrePostCaller(Foo()) a.stuff() a = PrePostCaller([1,2,3]) print a.count()
得到:
pre stuff post pre post 0
因此,在创建对象的实例时,请使用PrePostCaller对象进行包装.之后,继续使用该对象,就好像它是包装对象的实例一样.使用此解决方案,您可以基于每个实例进行包装.
以下是我和我的同事提出的解决方案:
from types import MethodType class PrePostCaller: def __init__(self, other): self.other = other def pre(self): print 'pre' def post(self): print 'post' def __getattr__(self, name): if hasattr(self.other, name): func = getattr(self.other, name) return lambda *args, **kwargs: self._wrap(func, args, kwargs) raise AttributeError(name) def _wrap(self, func, args, kwargs): self.pre() if type(func) == MethodType: result = func( *args, **kwargs) else: result = func(self.other, *args, **kwargs) self.post() return result #Examples of use class Foo: def stuff(self): print 'stuff' a = PrePostCaller(Foo()) a.stuff() a = PrePostCaller([1,2,3]) print a.count()
得到:
pre stuff post pre post 0
因此,在创建对象的实例时,请使用PrePostCaller对象进行包装.之后,继续使用该对象,就好像它是包装对象的实例一样.使用此解决方案,您可以基于每个实例进行包装.