2

I want to call a wrapper method of function with argument just before I call specific method. So I guess I have to ovewrite __getattribute__ method.

Here is an example of code:

def wrapper(func):
    return func * 2

class A(object):
    def test(self, arg):
        return arg + 1

    def __getattribute__(self, name):
        if name in ['test']:
            return wrapper(super(A, self).__getattribute__(name))
        return super(A, self).__getattribute__(name)

The matter is that getattribute is called when test return the value. What I want is to be able to catch test with the arguments and define the wrapper method like this:

def wrapper(func, *args, **kwargs):
    print "do some stuff"
    return func(*args, **kwargs)
2
  • 1
    Did you mean to place your parentheses as follows return wrapper(super(A, self).__getattribute__)(name)? Commented Sep 1, 2014 at 14:16
  • @DavidRobinson: no, that'd not actually retrieve the method object. Take a look at my answer, where I separate out the super() call and the wrapping. Commented Sep 1, 2014 at 14:17

2 Answers 2

4

Use a factory function to return your wrapper:

def decorate(f):
    def wrapper(*args, **kw):
        return f(*args, **kw) * 2
    return wrapper

Here f is closed over by wrapper(), so it can access the name when called.

Then return this in the __getattribute__ hook:

def __getattribute__(self, name):
    result = super(A, self).__getattribute__(name)
    if name in ('test',):
        return decorate(result)
    return result

Of course, you could also just apply decorate as a decorator on test then:

class A(object):
    @decorate
    def test(self, arg):
        return arg + 1
Sign up to request clarification or add additional context in comments.

2 Comments

Ty for help. I can not change or affect wrapper (from another class). But I guess my only choice is to make a decorator on test method and I don't need to use __getattribute__.
@Katsu: yes, that'd be the better option. I assumed that wasn't an option for you.
1

If I understand you correctly, you can use a decorator.

def wrapper(func):
    def _wrapper(*args, **kwargs):
        return func(*args, **kwargs) * 2

    return _wrapper

class A(object):
    @wrapper
    def test(self, arg):
        return arg + 1

1 Comment

+1: Yes it was I suggested previous comment Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.