1

I have a hierarchy of classes with a whole bunch of similar methods that I've managed to factor out the common parts of using a closure and a decorator:

def makemethod(kernel_method, output_class):
    def closure(self, start, end):
        set().up()
        common()
        stuff()
        result = []
        for i in range(start, end):
            args = more().standard().stuff()
            result.append(kernel_method(self, args))
        finish().up()
        return output_class(result)
    return closure

def mymethod(output_class):
    def decorator(kernel_method):
        return makemethod(kernel_method, output_class)
    return decorator

Each method that follows the pattern, whether it's a method defined in the base class or a derived class, just has to define its "kernel" and use the decorator to wrap it in the common code:

@mymethod(Class1)
def a_method_that_builds_a_Class1(self, args):
    # just the kernel!

@mymethod(Class2)
def a_method_that_builds_a_Class2(self, args):
    # just the kernel!

@mymethod(Class2)
def a_different_way_to_build_a_Class2(self, args):
    # just the kernel!

All of this works beautifully and does exactly what I want it to. The only problem is, to make it work I've had to define the makemethod function and its decorator wrapper outside of my base class, as module-level functions, and that seems awfully weird to me (though maybe in Python it's not weird at all?)

The inner function closure makes absolutely no sense except as a method of my class (the "common stuff" it does uses all kinds of class attributes), so the outer function that it's defined inside should be a class member, right? But if I try to make the outer functions static or class methods of my base class, I can use them to decorate methods of derived classes, but I can't call them in the base class itself, because inside a class's definition its own name isn't in scope yet. And my base class does have methods that need decorating.

I suppose I could put the closure and decorator in a class on their own, and have my "base" class inherit from that class. Is that what I should do, or is it stylistically okay in Python for closure/decorator "templates" for methods to be module-level functions?

Alex Jackson
  • 149
  • 4
  • Are you using python2 or python3? The behavior of class definition differs a bit, but in all there's no restriction that a decorator cannot reside inside a class or wherever (the only obstacle may be to get them there correctly). – skyking Sep 10 '15 at 10:04
  • It's not the answer, but you could derive your base class from BaseClassDecorators. Here is similar question: http://stackoverflow.com/questions/11740626/can-a-class-method-be-a-decorator – Piotr Jaszkowski Sep 10 '15 at 10:07

0 Answers0