Using python decorators for class methods and subclass methods

Goal. Allow decorating class methods. When a class method is decorated, it is stored in a dictionary, so other class methods can refer to it by string name.

Motivation: I want to implement the ASP.Net WebMethods equivalent. I am building this on top of google engine, but it does not affect what I have.

What it would look like if it worked:

class UsefulClass(WebmethodBaseClass):
    def someMethod(self, blah):
        print(blah)

    @webmethod
    def webby(self, blah):
        print(blah)

# the implementation of this class could be completely different, it does not matter
# the only important thing is having access to the web methods defined in sub classes
class WebmethodBaseClass():
    def post(self, methodName):
        webmethods[methodName]("kapow")

    ...    

a = UsefulClass()
a.post("someMethod") # should error
a.post("webby")  # prints "kapow"

      

There may be other ways. I am very open to suggestions

+2


a source to share


3 answers


It's not needed. Just use getattr

:

class WebmethodBaseClass():
    def post(self, methodName):
        getattr(self, methodName)("kapow")

      

The only caveat is that you must make sure that only methods that are intended to be used as web methods can be used. The simplest solution IMO is to accept the convention that non-web methods start with an underscore and the method post

refuses to serve such names.



If you really want to use decorators, try this:

def webmethod(f):
    f.is_webmethod = True
    return f

      

and get post

to check for the existence of the attribute is_webmethod

before calling the method.

+4


a source


This would seem to be the easiest way to satisfy your specifications:

webmethods = {}

def webmethod(f):
    webmethods[f.__name__] = f
    return f

      

and, in WebmethodBaseClass

,



def post(self, methodName):
    webmethods[methodName](self, "kapow")

      

I suspect you want something different (like separate namespaces for different subclasses and one global dictionary webmethods

...?), But it's hard to guess without elaborating how your desires differ from your specs - so maybe you can tell us, how this simplified approach does not allow you to achieve some of your desires, so it can be enriched according to what you really want.

+1


a source


class UsefulClass(WebmethodBaseClass):

    def someMethod(self, blah):
        print(blah)

    @webmethod
    def webby(self, blah):
        print(blah)

class WebmethodBaseClass():
    def post(self, methodName):
        method = getattr(self, methodName)
        if method.webmethod:
            method("kapow")

    ...

def webmethod(f):
    f.webmethod = True
    return f

a = UsefulClass()
a.post("someMethod") # should error
a.post("webby")  # prints "kapow"

      

0


a source







All Articles