Note:

The accepted answer on the other question shows how to use the parent decorater.

The accepted answer on this question shows moving the decorator to the module scope.


EDIT: Using the previous example was a bad idea. Hopefully this is more clear:

class A:
    def deco( func ):
        print repr(func)
        def wrapper( self, *args ):
            val = func( *args )
            self.do_something()
            return val
        return wrapper

    def do_something( self ):
        # Do something
        print 'A: Doing something generic for decoration'

    @deco
    def do_some_A_thing ( self ):
        # Do something 
        print 'A: Doing something generic'

class B ( A ):

    @deco
    def do_some_B_thing( self ):
        # Do something
        print "B: Doing something specific"

a = A()
b = B()
a.do_some_A_thing()
b.do_some_B_thing()

#Expected Output:
    #A: Doing something generic
    #A: Doing something generic for decoration
    #B: Doing something specific
    #A: Doing something generic for decoration

This code generates a NameError: name 'deco' is not defined inside B. The decorator needs to be inside the class scope because I require access to stored state.

Third Edit: On Sven's suggestions, I tried this:

class A:
    def deco( func ):
        def wrapper( self, *args ):
            val = func( *args )
            self.do_something(*args)
            return val
        return wrapper

    def do_something( self ):
        # Do something
        print 'A: Doing something generic for decoration'

    @deco
    def do_some_A_thing ( self ):
        # Do something 
        print 'A: Doing something generic'

    deco = staticmethod(deco)

class B ( A ):

    @A.deco
    def do_some_B_thing( self ):
        # Do something
        print "B: Doing something specific"



a = A()
b = B()
a.do_some_A_thing()
b.do_some_B_thing(
Edit
Report