NULL NULL - 2 months ago 11
Python Question

Overloading and wrapping method of field of parent class in python

For example I have something like this:

class A(object):
def __init__(self):
pass

def foo(self, a, b, c):
return a + b + c


class B(object):
def __init__(self):
self.b = A()


def wrapper_func(func):

def wrapper(self, *args, **kwargs):
return func(self, a=3, *args, **kwargs)

return wrapper


class C(B):
def __init__(self):
pass

@wrapper_func
def ???


Is it possible to some how overload and then wrap method
foo
of the field of parent
B
class in python without inherits from class
A
? I need the wrapper indeed because I have the different methods with same arguments, but in the same time I have to save original class B methods native (besides overloading).

Answer

Initialize C's parent class using super and then pass all the parameters to the foo method of the composed class instance A() via the inherited attribute b of the class C:

def wrapper_func(func):
    def wrapper(self, *args, **kwargs):
        kwargs['a'] = 3
        return func(self, *args, **kwargs)
    return wrapper


class C(B):
    def __init__(self):
        super(C, self).__init__()

    @wrapper_func
    def bar(self, *args, **kwargs):
        return self.b.foo(*args, **kwargs) # access foo via attribute b

Trial:

c = C()
print(c.bar(a=1, b=2, c=3))
# 8  -> 3+2+3

To make the call to the decorated function via c.b.foo, patch the c.b.foo method with the new bar method:

class C(B):
    def __init__(self):
        super(C, self).__init__()
        self._b_foo = self.b.foo
        self.b.foo = self.bar

    @wrapper_func
    def bar(self, *args, **kwargs):
        return self._b_foo(*args, **kwargs) 

Trial:

c = C()
print(c.b.foo(a=1, b=2, c=3))
# 8  -> 3+2+3
Comments