在类方法和子类方法上使用python decorators

时间:2010-04-26 04:04:04

标签: python decorator

目标:可以装饰类方法。当类方法被装饰时,它被存储在字典中,以便其他类方法可以通过字符串名称引用它。

动机:我想实现相当于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"

还有其他方法可以解决这个问题。我对建议很开放

3 个答案:

答案 0 :(得分:4)

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

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

唯一需要注意的是,您必须确保只能使用打算用作web方法的方法。最简单的解决方案IMO是采用非web方法以下划线开头并且post方法拒绝为这些名称提供服务的约定。

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

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

并在调用方法之前让post检查是否存在is_webmethod属性。

答案 1 :(得分:1)

这似乎是满足您所述规格的最简单方法:

webmethods = {}

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

,在WebmethodBaseClass中,

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

我怀疑你想要一些不同的东西(例如,不同的子类与单个全局webmethods字典的单独命名空间......?),但如果没有更多信息确切地说你的欲望与你的规格不同,很难猜测 - - 所以也许你可以告诉我们这种简单化的方法如何无法实现你的一些需求,所以它可以根据你真正想要的东西来丰富。

答案 2 :(得分: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"