wrapping a method function call?

Diez B. Roggisch deets at nospam.web.de
Mon Nov 3 09:28:00 CET 2008


mh at pixar.com schrieb:
> 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
> 
> Many TIA!
> Mark
> 
> 
> 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()

There are a few ways to accompish this. First of all, Python allows 
monkey-patching. That means you *can* modify it:
import sys


class X(object):
     def foo(self):
         print "foo"


X.foo = lambda self: sys.stdout.write("more than foo")

x = X()
x.foo()


You can of course wrap the old foo instead of replacing it, with 
something like

def foowrapper(old_foo):

    def _w(self, *args, **kwargs):
        print "wrapped"
        return old_foo(self, *args, **kwargs)

    return _w

X.foo = foowrapper(X.foo)


Alternatively, you can wrap the whole of X into a proxy, based on 
__getattr__ that will allow you do intercept all delegate calls.


class Wrapper(object):
    def __init__(self, delegate):
        self._delegate = delegate

    def __getattr__(self, name):
        print "accessing", name
        return getattr(self._delegate, name)


Diez






More information about the Python-list mailing list