GoingMyWay
GoingMyWay

Reputation: 17468

python, how to call instance's attribute in decorator

How to call instance attribute in decorator in decorator. The following are my test codes:

#!/usr/bin/env python
# coding=utf-8

class Foo(object):
    """"""
    def __init__(self):
        """"""
        self.a = 1

    def decorator(func):
        def wrapper(*args, **kw):
            """"""
            print self.a # or do something with self.a
            self.a += 1
        return wrapper

    @decorator
    def call_decorator(self):
        """"""
        pass

and

In [1]: import foo

In [2]: f = foo.Foo()

In [3]: f.call_decorator
Out[3]: <bound method Foo.wrapper of <foo.Foo object at 0x7fcc72c6a710>>

In [4]: f.call_decorator()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-4-70d92b784c01> in <module>()
----> 1 f.call_decorator()

/home/fit/log/1228/foo.py in wrapper(*args, **kw)
     11         def wrapper(*args, **kw):
     12             """"""
---> 13             print self.a
     14         return wrapper
     15 

NameError: global name 'self' is not defined

In [5]: 

And if I add self in def decorator(self, func):, and error will occur in @decorator, it needs 2 arguments. Decorator is not easy to understand.

So, I just want to use the attribute a of instance f in the decorator, how can I do it?

Upvotes: 0

Views: 115

Answers (1)

bereal
bereal

Reputation: 34282

That's wrapper who receives self among any other function's arguments, not decorator, so the definition should be like:

def decorator(func):
    @functools.wraps(func)  # a good thing to do
    def wrapper(self, *args, **kw):
        print self.a # or do something with self.a
        self.a += 1
        # if you need to call it, otherwise what's the point of the decorator:
        return func(self, *args, **kw)  
    return wrapper

Upvotes: 1

Related Questions