2014-01-24 118 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“结果并将其添加到预期的输出中