hcvst hcvst - 21 days ago 6
Python Question

Python decorators in classes

Can one write sth like:

class Test(object):
def _decorator(self, foo):
foo()

@self._decorator
def bar(self):
pass


This fails: self in @self is unknown

I also tried:

@Test._decorator(self)


which also fails: Test unknown

If would like to temp. change some instance variables
in the decorator and the run the decorated method, before
changing them back.

Thanks.

Answer

What you're wanting to do isn't possible. Take, for instance, whether or not the code below looks valid:

class Test(object):

    def _decorator(self, foo):
        foo()

    def bar(self):
        pass
    bar = self._decorator(bar)

It, of course, isn't valid since self isn't defined at that point. The same goes for Test as it won't be defined until the class itself is defined (which its in the process of). I'm showing you this code snippet because this is what your decorator snippet transforms into.

So, as you can see, accessing the instance in a decorator like that isn't really possible since decorators are applied during the definition of whatever function/method they are attached to and not during instantiation.

If you need class-level access, try this:

class Test(object):

    @classmethod
    def _decorator(cls, foo):
        foo()

    def bar(self):
        pass
Test.bar = Test._decorator(Test.bar)