On Mon, 03 Nov 2008 08:17:02 +0000, mh wrote: > I am instantiating a class A (which I am importing from somebody else, > so I can't modify it) into my class X. > > Is there a way I can intercept or wrape calls to methods in A? I.e., in > the code below can I call > > x.a.p1() > > and get the output > > X.pre > A.p1 > X.post
Possibly you can do it with some metaclass magic. You might like to search for Eiffel-style pre- and post-conditions using a metaclass, although I warn you, many people consider metaclasses deep voodoo. Here's one way using decorators: # Define two decorator factories. def precall(pre): def decorator(f): def newf(*args, **kwargs): pre() return f(*args, **kwargs) return newf return decorator def postcall(post): def decorator(f): def newf(*args, **kwargs): x = f(*args, **kwargs) post() return x return newf return decorator Now you can monkey patch class A if you want. It's probably not a great idea to do this in production code, as it will effect class A everywhere. def pre(): print 'X.pre' def post(): print 'X.post' from module import A A.p1 = precall(pre)(postcall(post)(A.p1)) Here's another way: class A: # in my real application, this is an imported class # that I cannot modify def p1(self): print 'A.p1' class WrapA: def __init__(self, ainstance, xinstance): self._a = ainstance self._x = xinstance def p1(self): # Delegate calls as needed. self._x.pre() self._a.p1() self._x.post() class X: def __init__(self): self.a = WrapA(A(), self) def pre(self): print 'X.pre' def post(self): print 'X.post' There are probably many other ways to accomplish the same thing, depending on your exact requirements. You should be able to combine the decorator technique and the delegation technique to leave class A untouched outside of class X, but wrapped inside of X. -- Steven -- http://mail.python.org/mailman/listinfo/python-list