Goal: Make it possible to decorate class methods. When a class method gets decorated, it gets stored in a dictionary so that other class methods can reference it by a string name.
Motivation: I want to implement the equivalent of ASP.Net's WebMethods. I am building this on top of google app engine, but that does not affect the point of difficulty that I am having.
How it Would look if it worked:
class UsefulClass(WebmethodBaseClass):
def someMethod(self, blah):
print(blah)
@webmethod
def webby(self, blah):
print(blah)
# the implementation of this开发者_StackOverflow 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 could be other ways to go about this. I am very open to suggestions
This is unnecessary. Just use getattr
:
class WebmethodBaseClass():
def post(self, methodName):
getattr(self, methodName)("kapow")
The only caveat is that you have to make sure that only methods intended for use as webmethods can be used thus. The simplest solution, IMO, is to adopt the convention that non-webmethods start with an underscore and have the post
method refuse to service 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 is_webmethod
attribute before calling the method.
This would seem to be the simplest approach to meet your specs as stated:
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 (e.g., separate namespaces for different subclasses vs a single global webmethods
dictionary...?), but it's hard to guess without more info exactly how your desires differ from your specs -- so maybe you can tell us how this simplistic approach fails to achieve some of your desiderata, so it can be enriched according to what you actually want.
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"
精彩评论