2010-04-26 110 views
2

目标:使装饰类方法成为可能。当一个类方法被装饰时,它被存储在一个字典中,以便其他类方法可以通过字符串名称引用它。在类方法和子类方法上使用python装饰器

动机:我想实现ASP.Net的WebMethods的等价物。我正在谷歌应用程序引擎之上构建这个,但这并不影响我所遇到的难点。

会如何看待它的工作:

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" 

可能有其他的方式去了解这一点。我非常乐于提供建议

回答

4

这是不必要的。只需使用getattr

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

唯一需要注意的是,你必须确保旨在仅作为方法webMethods的可以这样使用。最简单的解决方案IMO是采用非webmethods以下划线开头的约定,并且post方法拒绝为这些名称提供服务。

如果你真的想使用的装饰,试试这个:

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

,并得到post调用方法前检查的is_webmethod属性的存在。

1

这似乎是最简单的方法来满足您的规格为表示:

webmethods = {} 

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

,并在WebmethodBaseClass

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

我怀疑你想要的东西不同(例如,对于不同的命名空间不同的子类与单个全球字典...?),但如果没有更多的信息,很难猜测你的欲望与你的规格有什么不同 - 所以也许你可以告诉我们这种简单的方法如何不能实现你的一些愿望erata,所以它可以根据你真正想要的内容来丰富。

0
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"