Overloading and wrapping method of field of parent class in python

By : NULL
Source: Stackoverflow.com
Question!

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).

By : NULL


Answers

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


You can check for yourself:

Measure-Command {
    1..100000 | ForEach-Object $_
}

1.17s

Measure-Command {
    foreach ($i in (1..100000))
    {
    $i
    }
}

0.15s
By : Avshalom


Yes, there is a performance difference. foreach is faster than ForEach-Object, but requires more memory, because all items ($folders) must be in memory. ForEach-Object processes one item at a time as they're passed through the pipeline, so it has a smaller memory footprint, but isn't as fast as foreach.

See also.



This video can help you solving your question :)
By: admin