2010-04-26 3 views
2

Цель: сделать возможным декорирование методов класса. Когда метод класса оформляется, он сохраняется в словаре, поэтому другие методы класса могут ссылаться на него по имени строки.Используйте декораторы python для методов класса и методов подкласса

Мотивация: Я хочу реализовать эквивалент WebMethodов ASP.Net. Я создаю это поверх движка Google, но это не влияет на ту сложность, которая у меня есть.

Как это будет выглядеть, если он работал:

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, является принятие конвенции о том, что не-web-методы начинаются с подчеркивания, и метод 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") 

Я подозреваю, что вы хотите что-то другое (например, отдельные пространства имен для разные подклассы против одного глобального словаря webmethods ...?), но трудно догадаться, не уточняя, как ваши желания отличаются от ваших спецификаций - так что, возможно, вы можете рассказать нам, как этот упрощенный подход не позволяет достичь некоторых ваших желаний 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" 
Смежные вопросы