2014-11-16 128 views
1

我想装饰一个类的方法,但不能完全弄清楚如何去做。最小类例如:装饰类的方法

class Circle(object): 
    def __init__(self,radius): 
     self.R = radius 

    def arc_length(self,theta): 
     return self.R*theta 

现在让我们说,我想另一个更是把arc_length总是相对于弧长的一些特定的其他值的方法,所以我定义一个函数如下:

def relative(rel_val): 
    def decorator(fn): 
     def wrapper(*args): 
      return fn(*args) - fn(rel_val) 
     return wrapper 
    return decorator 

所以现在我我班扩大到:

class Circle(object): 
    def __init__(self,radius): 
     self.R = radius 

    def arc_length(self,theta): 
     return self.R*theta 

    @relative(0.2) 
    def relative_arc_length(self,theta): 
     return self.arc_length(theta) 

我希望这将得到期望的行为,但我得到的错误: relative_arc_length()到底需要2 argum (1给出)

我认为这是与自我参数有关,但如果我将自己添加到fn(self,rel_val)的相对定义中,它会给我:全局名称“self”未定义

那么我该如何解决这个问题?有趣的是,如果我这样做:

c = Circle(10) 
relative(0.2)(c.arc_length)(1.5) 

它按预期工作。

任何人都可以指出我要出错的地方吗?另外,是否可以在类中定义装饰函数,如果是这样,我应该这样做吗?这是不错的编程习惯吗?

回答

1
return fn(*args) - fn(rel_val) 

方法总是以self作为第一个参数调用。因此,就你的情况而言,你将所有参数都传递给第一个电话,但在第二个电话中忘记了self

你将不得不提取argsself,并通过太:

obj, value = args 
return fn(obj, value) - fn(obj, rel_value) 

你或许应该包括检查,以确保只有准确地在任何时间太长两个值args,所以你不”不小心将装饰器用于不兼容的方法。