装饰一个类方法

时间:2014-11-16 17:10:20

标签: python class decorator

我想装饰一个类方法,但无法弄清楚如何做到这一点。最小类示例:

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个参数(给定1个)

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

那么我该如何解决这个问题呢?有趣的是,如果我做以下事情:

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

它按预期工作。

有人能指出我哪里出错了吗?此外,是否可以在类中定义装饰函数,如果是,我应该这样做吗?这是很好的编程习惯吗?

1 个答案:

答案 0 :(得分:2)

return fn(*args) - fn(rel_val)

始终使用self作为第一个参数调用方法。因此,在您的情况下,您将所有参数传递给第一个调用,但在第二个调用中忘记self

您必须从self中提取args并将其传递出去:

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

您应该包含一个检查,以确保args中任何时候只有两个值,因此您不会意外地使用装饰器来处理不兼容的方法。

相关问题