2014-01-24 154 views
3

我大部分工作正常。我想要一個類裝飾器(Decorator類),它接受可用於在對象上包裝方法的參數(greetingfarewell)(Person的實例)。帶參數的Python類裝飾器,但沒有運行裝飾函數

一切工作正常,除...原始命令功能Person類永遠不會運行!如果我使用類似

output = getattr(instance, func.func_name)(command, *args, **kwargs) 

手動調用函數我得到無限遞歸。

我該怎麼做?完整的代碼如下:

import functools 

class Decorator(object): 
    def __init__(self, greeting, farewell, *args, **kwargs): 
     print "initing" 
     self.greeting = greeting 
     self.farewell = farewell 

    def __call__(self, func, *args, **kwargs): 
     print "CALLING" 

     @functools.wraps(func) 
     def wrapper(instance, command, *args, **kwargs): 
      return "%s, %s! %s!\n%s, %s!" % (
       self.greeting, 
       instance.name, 
       command, 
       self.farewell, 
       instance.name 
      ) 
     return wrapper 

class Person(object): 
    def __init__(self, name): 
     self.name = name 

    @Decorator("Hello", "Goodbye") 
    def command(self, data): 
     return data + "LIKE A BOSS" 

s = Person("Bob") 
print s.command("eat food") 

實際輸出:

initing 
CALLING 
Hello, Bob! eat food! 
Goodbye, Bob! 

預期輸出:

initing 
CALLING 
Hello, Bob! eat food LIKE A BOSS! 
Goodbye, Bob! 
+0

根據您的使用示例,'__call__'只需要一個參數:'func'。 –

回答

4

您從未呼叫func以獲取原始消息:

def wrapper(instance, command, *args, **kwargs): 
      original_value = func(instance, command) #call func here 
      return "%s, %s! %s!\n%s, %s!" % (
       self.greeting, 
       instance.name, 
       original_value, 
       self.farewell, 
       instance.name 
      ) 

輸出:

initing 
CALLING 
Hello, Bob! eat food LIKE A BOSS! 
Goodbye, Bob! 
0

必須某處調用FUNC(數據)在您的包裝獲得「LIKE一個BOSS「結果並將其添加到預期的輸出中